comparison src/share/vm/gc_implementation/g1/concurrentMark.cpp @ 1044:6270f80a7331

6890137: G1: revamp reachable object dump Summary: Revamp the reachable object dump debugging facility. Reviewed-by: jmasa, apetrusenko
author tonyp
date Wed, 30 Sep 2009 14:50:51 -0400
parents dfdaf65c3423
children 44f61c24ddab
comparison
equal deleted inserted replaced
1043:fc06cd9b42c7 1044:6270f80a7331
665 // This closure is used to mark refs into the g1 generation 665 // This closure is used to mark refs into the g1 generation
666 // from external roots in the CMS bit map. 666 // from external roots in the CMS bit map.
667 // Called at the first checkpoint. 667 // Called at the first checkpoint.
668 // 668 //
669 669
670 #define PRINT_REACHABLE_AT_INITIAL_MARK 0
671 #if PRINT_REACHABLE_AT_INITIAL_MARK
672 static FILE* reachable_file = NULL;
673
674 class PrintReachableClosure: public OopsInGenClosure {
675 CMBitMap* _bm;
676 int _level;
677 public:
678 PrintReachableClosure(CMBitMap* bm) :
679 _bm(bm), _level(0) {
680 guarantee(reachable_file != NULL, "pre-condition");
681 }
682 void do_oop(oop* p) {
683 oop obj = *p;
684 HeapWord* obj_addr = (HeapWord*)obj;
685 if (obj == NULL) return;
686 fprintf(reachable_file, "%d: "PTR_FORMAT" -> "PTR_FORMAT" (%d)\n",
687 _level, p, (void*) obj, _bm->isMarked(obj_addr));
688 if (!_bm->isMarked(obj_addr)) {
689 _bm->mark(obj_addr);
690 _level++;
691 obj->oop_iterate(this);
692 _level--;
693 }
694 }
695 };
696 #endif // PRINT_REACHABLE_AT_INITIAL_MARK
697
698 #define SEND_HEAP_DUMP_TO_FILE 0
699 #if SEND_HEAP_DUMP_TO_FILE
700 static FILE* heap_dump_file = NULL;
701 #endif // SEND_HEAP_DUMP_TO_FILE
702
703 void ConcurrentMark::clearNextBitmap() { 670 void ConcurrentMark::clearNextBitmap() {
704 guarantee(!G1CollectedHeap::heap()->mark_in_progress(), "Precondition."); 671 guarantee(!G1CollectedHeap::heap()->mark_in_progress(), "Precondition.");
705 672
706 // clear the mark bitmap (no grey objects to start with). 673 // clear the mark bitmap (no grey objects to start with).
707 // We need to do this in chunks and offer to yield in between 674 // We need to do this in chunks and offer to yield in between
735 G1CollectedHeap* g1h = G1CollectedHeap::heap(); 702 G1CollectedHeap* g1h = G1CollectedHeap::heap();
736 G1CollectorPolicy* g1p = g1h->g1_policy(); 703 G1CollectorPolicy* g1p = g1h->g1_policy();
737 704
738 _has_aborted = false; 705 _has_aborted = false;
739 706
740 // Find all the reachable objects... 707 if (G1PrintReachableAtInitialMark) {
741 #if PRINT_REACHABLE_AT_INITIAL_MARK 708 print_reachable(true, "before");
742 guarantee(reachable_file == NULL, "Protocol"); 709 }
743 char fn_buf[100];
744 sprintf(fn_buf, "/tmp/reachable.txt.%d", os::current_process_id());
745 reachable_file = fopen(fn_buf, "w");
746 // clear the mark bitmap (no grey objects to start with)
747 _nextMarkBitMap->clearAll();
748 PrintReachableClosure prcl(_nextMarkBitMap);
749 g1h->process_strong_roots(true, // activate StrongRootsScope
750 false, // fake perm gen collection
751 SharedHeap::SO_AllClasses,
752 &prcl, // Regular roots
753 NULL, // do not visit active blobs
754 &prcl // Perm Gen Roots
755 );
756 // The root iteration above "consumed" dirty cards in the perm gen.
757 // Therefore, as a shortcut, we dirty all such cards.
758 g1h->rem_set()->invalidate(g1h->perm_gen()->used_region(), false);
759 fclose(reachable_file);
760 reachable_file = NULL;
761 // clear the mark bitmap again.
762 _nextMarkBitMap->clearAll();
763 COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
764 COMPILER2_PRESENT(DerivedPointerTable::clear());
765 #endif // PRINT_REACHABLE_AT_INITIAL_MARK
766 710
767 // Initialise marking structures. This has to be done in a STW phase. 711 // Initialise marking structures. This has to be done in a STW phase.
768 reset(); 712 reset();
769 } 713 }
770 714
1963 "Different number of objs processed and enqueued."); 1907 "Different number of objs processed and enqueued.");
1964 } 1908 }
1965 #endif 1909 #endif
1966 } 1910 }
1967 1911
1912 #ifndef PRODUCT
1913
1968 class ReachablePrinterOopClosure: public OopClosure { 1914 class ReachablePrinterOopClosure: public OopClosure {
1969 private: 1915 private:
1970 G1CollectedHeap* _g1h; 1916 G1CollectedHeap* _g1h;
1971 CMBitMapRO* _bitmap; 1917 CMBitMapRO* _bitmap;
1972 outputStream* _out; 1918 outputStream* _out;
1919 bool _use_prev_marking;
1973 1920
1974 public: 1921 public:
1975 ReachablePrinterOopClosure(CMBitMapRO* bitmap, outputStream* out) : 1922 ReachablePrinterOopClosure(CMBitMapRO* bitmap,
1976 _bitmap(bitmap), _g1h(G1CollectedHeap::heap()), _out(out) { } 1923 outputStream* out,
1924 bool use_prev_marking) :
1925 _g1h(G1CollectedHeap::heap()),
1926 _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { }
1977 1927
1978 void do_oop(narrowOop* p) { do_oop_work(p); } 1928 void do_oop(narrowOop* p) { do_oop_work(p); }
1979 void do_oop( oop* p) { do_oop_work(p); } 1929 void do_oop( oop* p) { do_oop_work(p); }
1980 1930
1981 template <class T> void do_oop_work(T* p) { 1931 template <class T> void do_oop_work(T* p) {
1986 if (!_g1h->is_in_g1_reserved(obj)) 1936 if (!_g1h->is_in_g1_reserved(obj))
1987 str = "outside G1 reserved"; 1937 str = "outside G1 reserved";
1988 else { 1938 else {
1989 HeapRegion* hr = _g1h->heap_region_containing(obj); 1939 HeapRegion* hr = _g1h->heap_region_containing(obj);
1990 guarantee(hr != NULL, "invariant"); 1940 guarantee(hr != NULL, "invariant");
1991 if (hr->obj_allocated_since_prev_marking(obj)) { 1941 bool over_tams = false;
1942 if (_use_prev_marking) {
1943 over_tams = hr->obj_allocated_since_prev_marking(obj);
1944 } else {
1945 over_tams = hr->obj_allocated_since_next_marking(obj);
1946 }
1947
1948 if (over_tams) {
1992 str = "over TAMS"; 1949 str = "over TAMS";
1993 if (_bitmap->isMarked((HeapWord*) obj)) 1950 if (_bitmap->isMarked((HeapWord*) obj)) {
1994 str2 = " AND MARKED"; 1951 str2 = " AND MARKED";
1995 } else if (_bitmap->isMarked((HeapWord*) obj)) 1952 }
1953 } else if (_bitmap->isMarked((HeapWord*) obj)) {
1996 str = "marked"; 1954 str = "marked";
1997 else 1955 } else {
1998 str = "#### NOT MARKED ####"; 1956 str = "#### NOT MARKED ####";
1957 }
1999 } 1958 }
2000 1959
2001 _out->print_cr(" "PTR_FORMAT" contains "PTR_FORMAT" %s%s", 1960 _out->print_cr(" "PTR_FORMAT" contains "PTR_FORMAT" %s%s",
2002 p, (void*) obj, str, str2); 1961 p, (void*) obj, str, str2);
2003 } 1962 }
2004 }; 1963 };
2005 1964
2006 class ReachablePrinterClosure: public BitMapClosure { 1965 class ReachablePrinterClosure: public BitMapClosure {
2007 private: 1966 private:
2008 CMBitMapRO* _bitmap; 1967 CMBitMapRO* _bitmap;
2009 outputStream* _out; 1968 outputStream* _out;
1969 bool _use_prev_marking;
2010 1970
2011 public: 1971 public:
2012 ReachablePrinterClosure(CMBitMapRO* bitmap, outputStream* out) : 1972 ReachablePrinterClosure(CMBitMapRO* bitmap,
2013 _bitmap(bitmap), _out(out) { } 1973 outputStream* out,
1974 bool use_prev_marking) :
1975 _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { }
2014 1976
2015 bool do_bit(size_t offset) { 1977 bool do_bit(size_t offset) {
2016 HeapWord* addr = _bitmap->offsetToHeapWord(offset); 1978 HeapWord* addr = _bitmap->offsetToHeapWord(offset);
2017 ReachablePrinterOopClosure oopCl(_bitmap, _out); 1979 ReachablePrinterOopClosure oopCl(_bitmap, _out, _use_prev_marking);
2018 1980
2019 _out->print_cr(" obj "PTR_FORMAT", offset %10d (marked)", addr, offset); 1981 _out->print_cr(" obj "PTR_FORMAT", offset %10d (marked)", addr, offset);
2020 oop(addr)->oop_iterate(&oopCl); 1982 oop(addr)->oop_iterate(&oopCl);
2021 _out->print_cr(""); 1983 _out->print_cr("");
2022 1984
2024 } 1986 }
2025 }; 1987 };
2026 1988
2027 class ObjInRegionReachablePrinterClosure : public ObjectClosure { 1989 class ObjInRegionReachablePrinterClosure : public ObjectClosure {
2028 private: 1990 private:
2029 CMBitMapRO* _bitmap; 1991 CMBitMapRO* _bitmap;
2030 outputStream* _out; 1992 outputStream* _out;
1993 bool _use_prev_marking;
2031 1994
2032 public: 1995 public:
1996 ObjInRegionReachablePrinterClosure(CMBitMapRO* bitmap,
1997 outputStream* out,
1998 bool use_prev_marking) :
1999 _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { }
2000
2033 void do_object(oop o) { 2001 void do_object(oop o) {
2034 ReachablePrinterOopClosure oopCl(_bitmap, _out); 2002 ReachablePrinterOopClosure oopCl(_bitmap, _out, _use_prev_marking);
2035 2003
2036 _out->print_cr(" obj "PTR_FORMAT" (over TAMS)", (void*) o); 2004 _out->print_cr(" obj "PTR_FORMAT" (over TAMS)", (void*) o);
2037 o->oop_iterate(&oopCl); 2005 o->oop_iterate(&oopCl);
2038 _out->print_cr(""); 2006 _out->print_cr("");
2039 } 2007 }
2040
2041 ObjInRegionReachablePrinterClosure(CMBitMapRO* bitmap, outputStream* out) :
2042 _bitmap(bitmap), _out(out) { }
2043 }; 2008 };
2044 2009
2045 class RegionReachablePrinterClosure : public HeapRegionClosure { 2010 class RegionReachablePrinterClosure : public HeapRegionClosure {
2046 private: 2011 private:
2047 CMBitMapRO* _bitmap; 2012 CMBitMapRO* _bitmap;
2048 outputStream* _out; 2013 outputStream* _out;
2014 bool _use_prev_marking;
2049 2015
2050 public: 2016 public:
2051 bool doHeapRegion(HeapRegion* hr) { 2017 bool doHeapRegion(HeapRegion* hr) {
2052 HeapWord* b = hr->bottom(); 2018 HeapWord* b = hr->bottom();
2053 HeapWord* e = hr->end(); 2019 HeapWord* e = hr->end();
2054 HeapWord* t = hr->top(); 2020 HeapWord* t = hr->top();
2055 HeapWord* p = hr->prev_top_at_mark_start(); 2021 HeapWord* p = NULL;
2022 if (_use_prev_marking) {
2023 p = hr->prev_top_at_mark_start();
2024 } else {
2025 p = hr->next_top_at_mark_start();
2026 }
2056 _out->print_cr("** ["PTR_FORMAT", "PTR_FORMAT"] top: "PTR_FORMAT" " 2027 _out->print_cr("** ["PTR_FORMAT", "PTR_FORMAT"] top: "PTR_FORMAT" "
2057 "PTAMS: "PTR_FORMAT, b, e, t, p); 2028 "TAMS: "PTR_FORMAT, b, e, t, p);
2058 _out->print_cr(""); 2029 _out->print_cr("");
2059 2030
2060 ObjInRegionReachablePrinterClosure ocl(_bitmap, _out); 2031 ObjInRegionReachablePrinterClosure ocl(_bitmap, _out, _use_prev_marking);
2061 hr->object_iterate_mem_careful(MemRegion(p, t), &ocl); 2032 hr->object_iterate_mem_careful(MemRegion(p, t), &ocl);
2062 2033
2063 return false; 2034 return false;
2064 } 2035 }
2065 2036
2066 RegionReachablePrinterClosure(CMBitMapRO* bitmap, 2037 RegionReachablePrinterClosure(CMBitMapRO* bitmap,
2067 outputStream* out) : 2038 outputStream* out,
2068 _bitmap(bitmap), _out(out) { } 2039 bool use_prev_marking) :
2040 _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { }
2069 }; 2041 };
2070 2042
2071 void ConcurrentMark::print_prev_bitmap_reachable() { 2043 void ConcurrentMark::print_reachable(bool use_prev_marking, const char* str) {
2072 outputStream* out = gclog_or_tty; 2044 gclog_or_tty->print_cr("== Doing reachable object dump... ");
2073 2045
2074 #if SEND_HEAP_DUMP_TO_FILE 2046 if (G1PrintReachableBaseFile == NULL) {
2075 guarantee(heap_dump_file == NULL, "Protocol"); 2047 gclog_or_tty->print_cr(" #### error: no base file defined");
2076 char fn_buf[100]; 2048 return;
2077 sprintf(fn_buf, "/tmp/dump.txt.%d", os::current_process_id()); 2049 }
2078 heap_dump_file = fopen(fn_buf, "w"); 2050
2079 fileStream fstream(heap_dump_file); 2051 if (strlen(G1PrintReachableBaseFile) + 1 + strlen(str) >
2080 out = &fstream; 2052 (JVM_MAXPATHLEN - 1)) {
2081 #endif // SEND_HEAP_DUMP_TO_FILE 2053 gclog_or_tty->print_cr(" #### error: file name too long");
2082 2054 return;
2083 RegionReachablePrinterClosure rcl(_prevMarkBitMap, out); 2055 }
2084 out->print_cr("--- ITERATING OVER REGIONS WITH PTAMS < TOP"); 2056
2057 char file_name[JVM_MAXPATHLEN];
2058 sprintf(file_name, "%s.%s", G1PrintReachableBaseFile, str);
2059 gclog_or_tty->print_cr(" dumping to file %s", file_name);
2060
2061 fileStream fout(file_name);
2062 if (!fout.is_open()) {
2063 gclog_or_tty->print_cr(" #### error: could not open file");
2064 return;
2065 }
2066
2067 outputStream* out = &fout;
2068
2069 CMBitMapRO* bitmap = NULL;
2070 if (use_prev_marking) {
2071 bitmap = _prevMarkBitMap;
2072 } else {
2073 bitmap = _nextMarkBitMap;
2074 }
2075
2076 out->print_cr("-- USING %s", (use_prev_marking) ? "PTAMS" : "NTAMS");
2077 out->cr();
2078
2079 RegionReachablePrinterClosure rcl(bitmap, out, use_prev_marking);
2080 out->print_cr("--- ITERATING OVER REGIONS WITH TAMS < TOP");
2081 out->cr();
2085 _g1h->heap_region_iterate(&rcl); 2082 _g1h->heap_region_iterate(&rcl);
2086 out->print_cr(""); 2083 out->cr();
2087 2084
2088 ReachablePrinterClosure cl(_prevMarkBitMap, out); 2085 ReachablePrinterClosure cl(bitmap, out, use_prev_marking);
2089 out->print_cr("--- REACHABLE OBJECTS ON THE BITMAP"); 2086 out->print_cr("--- ITERATING OVER MARKED OBJECTS ON THE BITMAP");
2090 _prevMarkBitMap->iterate(&cl); 2087 out->cr();
2091 out->print_cr(""); 2088 bitmap->iterate(&cl);
2092 2089 out->cr();
2093 #if SEND_HEAP_DUMP_TO_FILE 2090
2094 fclose(heap_dump_file); 2091 gclog_or_tty->print_cr(" done");
2095 heap_dump_file = NULL; 2092 }
2096 #endif // SEND_HEAP_DUMP_TO_FILE 2093
2097 } 2094 #endif // PRODUCT
2098 2095
2099 // This note is for drainAllSATBBuffers and the code in between. 2096 // This note is for drainAllSATBBuffers and the code in between.
2100 // In the future we could reuse a task to do this work during an 2097 // In the future we could reuse a task to do this work during an
2101 // evacuation pause (since now tasks are not active and can be claimed 2098 // evacuation pause (since now tasks are not active and can be claimed
2102 // during an evacuation pause). This was a late change to the code and 2099 // during an evacuation pause). This was a late change to the code and