comparison src/share/vm/gc_implementation/g1/heapRegion.cpp @ 2133:2250ee17e258

7007068: G1: refine the BOT during evac failure handling Summary: During evacuation failure handling we refine the BOT to reflect the location of all the objects in the regions we scan. The changeset includes some minor cleanup: a) non-product print_on() method on the G1 BOT class, b) added more complete BOT verification during heap / region verification, c) slight modification to the BOT set up for humongous regions to be more consistent with the BOT set up during evac failure handling, and d) removed a couple of unused methods. Reviewed-by: johnc, ysr
author tonyp
date Wed, 12 Jan 2011 13:06:00 -0500
parents f95d63e2154a
children 0fa27f37d4d4
comparison
equal deleted inserted replaced
2132:4947ee68d19c 2133:2250ee17e258
1 /* 1 /*
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2001, 2011, 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.
384 _gc_efficiency = (double) garbage_bytes() / 384 _gc_efficiency = (double) garbage_bytes() /
385 g1h->predict_region_elapsed_time_ms(this, false); 385 g1h->predict_region_elapsed_time_ms(this, false);
386 } 386 }
387 // </PREDICTION> 387 // </PREDICTION>
388 388
389 void HeapRegion::set_startsHumongous(HeapWord* new_end) { 389 void HeapRegion::set_startsHumongous(HeapWord* new_top, HeapWord* new_end) {
390 assert(end() == _orig_end, 390 assert(end() == _orig_end,
391 "Should be normal before the humongous object allocation"); 391 "Should be normal before the humongous object allocation");
392 assert(top() == bottom(), "should be empty"); 392 assert(top() == bottom(), "should be empty");
393 assert(bottom() <= new_top && new_top <= new_end, "pre-condition");
393 394
394 _humongous_type = StartsHumongous; 395 _humongous_type = StartsHumongous;
395 _humongous_start_region = this; 396 _humongous_start_region = this;
396 397
397 set_end(new_end); 398 set_end(new_end);
398 _offsets.set_for_starts_humongous(new_end); 399 _offsets.set_for_starts_humongous(new_top);
399 } 400 }
400 401
401 void HeapRegion::set_continuesHumongous(HeapRegion* start) { 402 void HeapRegion::set_continuesHumongous(HeapRegion* first_hr) {
402 assert(end() == _orig_end, 403 assert(end() == _orig_end,
403 "Should be normal before the humongous object allocation"); 404 "Should be normal before the humongous object allocation");
404 assert(top() == bottom(), "should be empty"); 405 assert(top() == bottom(), "should be empty");
405 assert(start->startsHumongous(), "pre-condition"); 406 assert(first_hr->startsHumongous(), "pre-condition");
406 407
407 _humongous_type = ContinuesHumongous; 408 _humongous_type = ContinuesHumongous;
408 _humongous_start_region = start; 409 _humongous_start_region = first_hr;
409 } 410 }
410 411
411 bool HeapRegion::claimHeapRegion(jint claimValue) { 412 bool HeapRegion::claimHeapRegion(jint claimValue) {
412 jint current = _claimed; 413 jint current = _claimed;
413 if (current != claimValue) { 414 if (current != claimValue) {
780 void HeapRegion::verify(bool allow_dirty) const { 781 void HeapRegion::verify(bool allow_dirty) const {
781 bool dummy = false; 782 bool dummy = false;
782 verify(allow_dirty, /* use_prev_marking */ true, /* failures */ &dummy); 783 verify(allow_dirty, /* use_prev_marking */ true, /* failures */ &dummy);
783 } 784 }
784 785
785 #define OBJ_SAMPLE_INTERVAL 0
786 #define BLOCK_SAMPLE_INTERVAL 100
787
788 // This really ought to be commoned up into OffsetTableContigSpace somehow. 786 // This really ought to be commoned up into OffsetTableContigSpace somehow.
789 // We would need a mechanism to make that code skip dead objects. 787 // We would need a mechanism to make that code skip dead objects.
790 788
791 void HeapRegion::verify(bool allow_dirty, 789 void HeapRegion::verify(bool allow_dirty,
792 bool use_prev_marking, 790 bool use_prev_marking,
793 bool* failures) const { 791 bool* failures) const {
794 G1CollectedHeap* g1 = G1CollectedHeap::heap(); 792 G1CollectedHeap* g1 = G1CollectedHeap::heap();
795 *failures = false; 793 *failures = false;
796 HeapWord* p = bottom(); 794 HeapWord* p = bottom();
797 HeapWord* prev_p = NULL; 795 HeapWord* prev_p = NULL;
798 int objs = 0;
799 int blocks = 0;
800 VerifyLiveClosure vl_cl(g1, use_prev_marking); 796 VerifyLiveClosure vl_cl(g1, use_prev_marking);
801 bool is_humongous = isHumongous(); 797 bool is_humongous = isHumongous();
798 bool do_bot_verify = !is_young();
802 size_t object_num = 0; 799 size_t object_num = 0;
803 while (p < top()) { 800 while (p < top()) {
804 size_t size = oop(p)->size(); 801 oop obj = oop(p);
805 if (is_humongous != g1->isHumongous(size)) { 802 size_t obj_size = obj->size();
803 object_num += 1;
804
805 if (is_humongous != g1->isHumongous(obj_size)) {
806 gclog_or_tty->print_cr("obj "PTR_FORMAT" is of %shumongous size (" 806 gclog_or_tty->print_cr("obj "PTR_FORMAT" is of %shumongous size ("
807 SIZE_FORMAT" words) in a %shumongous region", 807 SIZE_FORMAT" words) in a %shumongous region",
808 p, g1->isHumongous(size) ? "" : "non-", 808 p, g1->isHumongous(obj_size) ? "" : "non-",
809 size, is_humongous ? "" : "non-"); 809 obj_size, is_humongous ? "" : "non-");
810 *failures = true; 810 *failures = true;
811 } 811 return;
812 object_num += 1; 812 }
813 if (blocks == BLOCK_SAMPLE_INTERVAL) { 813
814 HeapWord* res = block_start_const(p + (size/2)); 814 // If it returns false, verify_for_object() will output the
815 if (p != res) { 815 // appropriate messasge.
816 gclog_or_tty->print_cr("offset computation 1 for "PTR_FORMAT" and " 816 if (do_bot_verify && !_offsets.verify_for_object(p, obj_size)) {
817 SIZE_FORMAT" returned "PTR_FORMAT, 817 *failures = true;
818 p, size, res); 818 return;
819 }
820
821 if (!g1->is_obj_dead_cond(obj, this, use_prev_marking)) {
822 if (obj->is_oop()) {
823 klassOop klass = obj->klass();
824 if (!klass->is_perm()) {
825 gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
826 "not in perm", klass, obj);
827 *failures = true;
828 return;
829 } else if (!klass->is_klass()) {
830 gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
831 "not a klass", klass, obj);
832 *failures = true;
833 return;
834 } else {
835 vl_cl.set_containing_obj(obj);
836 obj->oop_iterate(&vl_cl);
837 if (vl_cl.failures()) {
838 *failures = true;
839 }
840 if (G1MaxVerifyFailures >= 0 &&
841 vl_cl.n_failures() >= G1MaxVerifyFailures) {
842 return;
843 }
844 }
845 } else {
846 gclog_or_tty->print_cr(PTR_FORMAT" no an oop", obj);
819 *failures = true; 847 *failures = true;
820 return; 848 return;
821 } 849 }
822 blocks = 0;
823 } else {
824 blocks++;
825 }
826 if (objs == OBJ_SAMPLE_INTERVAL) {
827 oop obj = oop(p);
828 if (!g1->is_obj_dead_cond(obj, this, use_prev_marking)) {
829 if (obj->is_oop()) {
830 klassOop klass = obj->klass();
831 if (!klass->is_perm()) {
832 gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
833 "not in perm", klass, obj);
834 *failures = true;
835 return;
836 } else if (!klass->is_klass()) {
837 gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
838 "not a klass", klass, obj);
839 *failures = true;
840 return;
841 } else {
842 vl_cl.set_containing_obj(obj);
843 obj->oop_iterate(&vl_cl);
844 if (vl_cl.failures()) {
845 *failures = true;
846 }
847 if (G1MaxVerifyFailures >= 0 &&
848 vl_cl.n_failures() >= G1MaxVerifyFailures) {
849 return;
850 }
851 }
852 } else {
853 gclog_or_tty->print_cr(PTR_FORMAT" no an oop", obj);
854 *failures = true;
855 return;
856 }
857 }
858 objs = 0;
859 } else {
860 objs++;
861 } 850 }
862 prev_p = p; 851 prev_p = p;
863 p += size; 852 p += obj_size;
864 } 853 }
865 HeapWord* rend = end(); 854
866 HeapWord* rtop = top(); 855 if (p != top()) {
867 if (rtop < rend) { 856 gclog_or_tty->print_cr("end of last object "PTR_FORMAT" "
868 HeapWord* res = block_start_const(rtop + (rend - rtop) / 2); 857 "does not match top "PTR_FORMAT, p, top());
869 if (res != rtop) { 858 *failures = true;
870 gclog_or_tty->print_cr("offset computation 2 for "PTR_FORMAT" and " 859 return;
871 PTR_FORMAT" returned "PTR_FORMAT, 860 }
872 rtop, rend, res); 861
862 HeapWord* the_end = end();
863 assert(p == top(), "it should still hold");
864 // Do some extra BOT consistency checking for addresses in the
865 // range [top, end). BOT look-ups in this range should yield
866 // top. No point in doing that if top == end (there's nothing there).
867 if (p < the_end) {
868 // Look up top
869 HeapWord* addr_1 = p;
870 HeapWord* b_start_1 = _offsets.block_start_const(addr_1);
871 if (b_start_1 != p) {
872 gclog_or_tty->print_cr("BOT look up for top: "PTR_FORMAT" "
873 " yielded "PTR_FORMAT", expecting "PTR_FORMAT,
874 addr_1, b_start_1, p);
875 *failures = true;
876 return;
877 }
878
879 // Look up top + 1
880 HeapWord* addr_2 = p + 1;
881 if (addr_2 < the_end) {
882 HeapWord* b_start_2 = _offsets.block_start_const(addr_2);
883 if (b_start_2 != p) {
884 gclog_or_tty->print_cr("BOT look up for top + 1: "PTR_FORMAT" "
885 " yielded "PTR_FORMAT", expecting "PTR_FORMAT,
886 addr_2, b_start_2, p);
873 *failures = true; 887 *failures = true;
874 return; 888 return;
889 }
890 }
891
892 // Look up an address between top and end
893 size_t diff = pointer_delta(the_end, p) / 2;
894 HeapWord* addr_3 = p + diff;
895 if (addr_3 < the_end) {
896 HeapWord* b_start_3 = _offsets.block_start_const(addr_3);
897 if (b_start_3 != p) {
898 gclog_or_tty->print_cr("BOT look up for top + diff: "PTR_FORMAT" "
899 " yielded "PTR_FORMAT", expecting "PTR_FORMAT,
900 addr_3, b_start_3, p);
901 *failures = true;
902 return;
903 }
904 }
905
906 // Loook up end - 1
907 HeapWord* addr_4 = the_end - 1;
908 HeapWord* b_start_4 = _offsets.block_start_const(addr_4);
909 if (b_start_4 != p) {
910 gclog_or_tty->print_cr("BOT look up for end - 1: "PTR_FORMAT" "
911 " yielded "PTR_FORMAT", expecting "PTR_FORMAT,
912 addr_4, b_start_4, p);
913 *failures = true;
914 return;
875 } 915 }
876 } 916 }
877 917
878 if (is_humongous && object_num > 1) { 918 if (is_humongous && object_num > 1) {
879 gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is humongous " 919 gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is humongous "
880 "but has "SIZE_FORMAT", objects", 920 "but has "SIZE_FORMAT", objects",
881 bottom(), end(), object_num); 921 bottom(), end(), object_num);
882 *failures = true;
883 }
884
885 if (p != top()) {
886 gclog_or_tty->print_cr("end of last object "PTR_FORMAT" "
887 "does not match top "PTR_FORMAT, p, top());
888 *failures = true; 922 *failures = true;
889 return; 923 return;
890 } 924 }
891 } 925 }
892 926