# HG changeset patch # User tonyp # Date 1256923871 14400 # Node ID 29adffcb6a61ff438d8044a8cca3d5048805c845 # Parent 4926bf2d292fb1be78577f7ba84821b56a468877# Parent beb8f45ee9f08ba740ca3cf2a2742388bce63b83 Merge diff -r 4926bf2d292f -r 29adffcb6a61 src/cpu/x86/vm/assembler_x86.cpp --- a/src/cpu/x86/vm/assembler_x86.cpp Thu Oct 29 08:49:31 2009 -0700 +++ b/src/cpu/x86/vm/assembler_x86.cpp Fri Oct 30 13:31:11 2009 -0400 @@ -8214,6 +8214,15 @@ } } +// Used for storing NULLs. +void MacroAssembler::store_heap_oop_null(Address dst) { + if (UseCompressedOops) { + movl(dst, (int32_t)NULL_WORD); + } else { + movslq(dst, (int32_t)NULL_WORD); + } +} + // Algorithm must match oop.inline.hpp encode_heap_oop. void MacroAssembler::encode_heap_oop(Register r) { assert (UseCompressedOops, "should be compressed"); diff -r 4926bf2d292f -r 29adffcb6a61 src/cpu/x86/vm/assembler_x86.hpp --- a/src/cpu/x86/vm/assembler_x86.hpp Thu Oct 29 08:49:31 2009 -0700 +++ b/src/cpu/x86/vm/assembler_x86.hpp Fri Oct 30 13:31:11 2009 -0400 @@ -1682,6 +1682,17 @@ void load_heap_oop(Register dst, Address src); void store_heap_oop(Address dst, Register src); + + // This dummy is to prevent a call to store_heap_oop from + // converting a zero (like NULL) into a Register by giving + // the compiler two choices it can't resolve + + void store_heap_oop(Address dst, void* dummy); + + // Used for storing NULL. All other oop constants should be + // stored using routines that take a jobject. + void store_heap_oop_null(Address dst); + void encode_heap_oop(Register r); void decode_heap_oop(Register r); void encode_heap_oop_not_null(Register r); diff -r 4926bf2d292f -r 29adffcb6a61 src/cpu/x86/vm/templateTable_x86_64.cpp --- a/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Oct 29 08:49:31 2009 -0700 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Fri Oct 30 13:31:11 2009 -0400 @@ -139,7 +139,7 @@ } __ g1_write_barrier_pre(rdx, r8, rbx, val != noreg); if (val == noreg) { - __ store_heap_oop(Address(rdx, 0), NULL_WORD); + __ store_heap_oop_null(Address(rdx, 0)); } else { __ store_heap_oop(Address(rdx, 0), val); __ g1_write_barrier_post(rdx, val, r8, rbx); @@ -152,7 +152,7 @@ case BarrierSet::CardTableExtension: { if (val == noreg) { - __ store_heap_oop(obj, NULL_WORD); + __ store_heap_oop_null(obj); } else { __ store_heap_oop(obj, val); // flatten object address if needed @@ -168,7 +168,7 @@ case BarrierSet::ModRef: case BarrierSet::Other: if (val == noreg) { - __ store_heap_oop(obj, NULL_WORD); + __ store_heap_oop_null(obj); } else { __ store_heap_oop(obj, val); } diff -r 4926bf2d292f -r 29adffcb6a61 src/share/vm/gc_implementation/g1/concurrentMark.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Oct 29 08:49:31 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Fri Oct 30 13:31:11 2009 -0400 @@ -667,39 +667,6 @@ // Called at the first checkpoint. // -#define PRINT_REACHABLE_AT_INITIAL_MARK 0 -#if PRINT_REACHABLE_AT_INITIAL_MARK -static FILE* reachable_file = NULL; - -class PrintReachableClosure: public OopsInGenClosure { - CMBitMap* _bm; - int _level; -public: - PrintReachableClosure(CMBitMap* bm) : - _bm(bm), _level(0) { - guarantee(reachable_file != NULL, "pre-condition"); - } - void do_oop(oop* p) { - oop obj = *p; - HeapWord* obj_addr = (HeapWord*)obj; - if (obj == NULL) return; - fprintf(reachable_file, "%d: "PTR_FORMAT" -> "PTR_FORMAT" (%d)\n", - _level, p, (void*) obj, _bm->isMarked(obj_addr)); - if (!_bm->isMarked(obj_addr)) { - _bm->mark(obj_addr); - _level++; - obj->oop_iterate(this); - _level--; - } - } -}; -#endif // PRINT_REACHABLE_AT_INITIAL_MARK - -#define SEND_HEAP_DUMP_TO_FILE 0 -#if SEND_HEAP_DUMP_TO_FILE -static FILE* heap_dump_file = NULL; -#endif // SEND_HEAP_DUMP_TO_FILE - void ConcurrentMark::clearNextBitmap() { guarantee(!G1CollectedHeap::heap()->mark_in_progress(), "Precondition."); @@ -737,32 +704,9 @@ _has_aborted = false; - // Find all the reachable objects... -#if PRINT_REACHABLE_AT_INITIAL_MARK - guarantee(reachable_file == NULL, "Protocol"); - char fn_buf[100]; - sprintf(fn_buf, "/tmp/reachable.txt.%d", os::current_process_id()); - reachable_file = fopen(fn_buf, "w"); - // clear the mark bitmap (no grey objects to start with) - _nextMarkBitMap->clearAll(); - PrintReachableClosure prcl(_nextMarkBitMap); - g1h->process_strong_roots(true, // activate StrongRootsScope - false, // fake perm gen collection - SharedHeap::SO_AllClasses, - &prcl, // Regular roots - NULL, // do not visit active blobs - &prcl // Perm Gen Roots - ); - // The root iteration above "consumed" dirty cards in the perm gen. - // Therefore, as a shortcut, we dirty all such cards. - g1h->rem_set()->invalidate(g1h->perm_gen()->used_region(), false); - fclose(reachable_file); - reachable_file = NULL; - // clear the mark bitmap again. - _nextMarkBitMap->clearAll(); - COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); - COMPILER2_PRESENT(DerivedPointerTable::clear()); -#endif // PRINT_REACHABLE_AT_INITIAL_MARK + if (G1PrintReachableAtInitialMark) { + print_reachable(true, "before"); + } // Initialise marking structures. This has to be done in a STW phase. reset(); @@ -1965,15 +1909,21 @@ #endif } +#ifndef PRODUCT + class ReachablePrinterOopClosure: public OopClosure { private: G1CollectedHeap* _g1h; CMBitMapRO* _bitmap; outputStream* _out; + bool _use_prev_marking; public: - ReachablePrinterOopClosure(CMBitMapRO* bitmap, outputStream* out) : - _bitmap(bitmap), _g1h(G1CollectedHeap::heap()), _out(out) { } + ReachablePrinterOopClosure(CMBitMapRO* bitmap, + outputStream* out, + bool use_prev_marking) : + _g1h(G1CollectedHeap::heap()), + _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { } void do_oop(narrowOop* p) { do_oop_work(p); } void do_oop( oop* p) { do_oop_work(p); } @@ -1988,14 +1938,23 @@ else { HeapRegion* hr = _g1h->heap_region_containing(obj); guarantee(hr != NULL, "invariant"); - if (hr->obj_allocated_since_prev_marking(obj)) { + bool over_tams = false; + if (_use_prev_marking) { + over_tams = hr->obj_allocated_since_prev_marking(obj); + } else { + over_tams = hr->obj_allocated_since_next_marking(obj); + } + + if (over_tams) { str = "over TAMS"; - if (_bitmap->isMarked((HeapWord*) obj)) + if (_bitmap->isMarked((HeapWord*) obj)) { str2 = " AND MARKED"; - } else if (_bitmap->isMarked((HeapWord*) obj)) + } + } else if (_bitmap->isMarked((HeapWord*) obj)) { str = "marked"; - else + } else { str = "#### NOT MARKED ####"; + } } _out->print_cr(" "PTR_FORMAT" contains "PTR_FORMAT" %s%s", @@ -2005,16 +1964,19 @@ class ReachablePrinterClosure: public BitMapClosure { private: - CMBitMapRO* _bitmap; + CMBitMapRO* _bitmap; outputStream* _out; + bool _use_prev_marking; public: - ReachablePrinterClosure(CMBitMapRO* bitmap, outputStream* out) : - _bitmap(bitmap), _out(out) { } + ReachablePrinterClosure(CMBitMapRO* bitmap, + outputStream* out, + bool use_prev_marking) : + _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { } bool do_bit(size_t offset) { HeapWord* addr = _bitmap->offsetToHeapWord(offset); - ReachablePrinterOopClosure oopCl(_bitmap, _out); + ReachablePrinterOopClosure oopCl(_bitmap, _out, _use_prev_marking); _out->print_cr(" obj "PTR_FORMAT", offset %10d (marked)", addr, offset); oop(addr)->oop_iterate(&oopCl); @@ -2026,76 +1988,111 @@ class ObjInRegionReachablePrinterClosure : public ObjectClosure { private: - CMBitMapRO* _bitmap; + CMBitMapRO* _bitmap; outputStream* _out; + bool _use_prev_marking; public: + ObjInRegionReachablePrinterClosure(CMBitMapRO* bitmap, + outputStream* out, + bool use_prev_marking) : + _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { } + void do_object(oop o) { - ReachablePrinterOopClosure oopCl(_bitmap, _out); + ReachablePrinterOopClosure oopCl(_bitmap, _out, _use_prev_marking); _out->print_cr(" obj "PTR_FORMAT" (over TAMS)", (void*) o); o->oop_iterate(&oopCl); _out->print_cr(""); } - - ObjInRegionReachablePrinterClosure(CMBitMapRO* bitmap, outputStream* out) : - _bitmap(bitmap), _out(out) { } }; class RegionReachablePrinterClosure : public HeapRegionClosure { private: - CMBitMapRO* _bitmap; + CMBitMapRO* _bitmap; outputStream* _out; + bool _use_prev_marking; public: bool doHeapRegion(HeapRegion* hr) { HeapWord* b = hr->bottom(); HeapWord* e = hr->end(); HeapWord* t = hr->top(); - HeapWord* p = hr->prev_top_at_mark_start(); + HeapWord* p = NULL; + if (_use_prev_marking) { + p = hr->prev_top_at_mark_start(); + } else { + p = hr->next_top_at_mark_start(); + } _out->print_cr("** ["PTR_FORMAT", "PTR_FORMAT"] top: "PTR_FORMAT" " - "PTAMS: "PTR_FORMAT, b, e, t, p); + "TAMS: "PTR_FORMAT, b, e, t, p); _out->print_cr(""); - ObjInRegionReachablePrinterClosure ocl(_bitmap, _out); + ObjInRegionReachablePrinterClosure ocl(_bitmap, _out, _use_prev_marking); hr->object_iterate_mem_careful(MemRegion(p, t), &ocl); return false; } - RegionReachablePrinterClosure(CMBitMapRO* bitmap, - outputStream* out) : - _bitmap(bitmap), _out(out) { } + RegionReachablePrinterClosure(CMBitMapRO* bitmap, + outputStream* out, + bool use_prev_marking) : + _bitmap(bitmap), _out(out), _use_prev_marking(use_prev_marking) { } }; -void ConcurrentMark::print_prev_bitmap_reachable() { - outputStream* out = gclog_or_tty; - -#if SEND_HEAP_DUMP_TO_FILE - guarantee(heap_dump_file == NULL, "Protocol"); - char fn_buf[100]; - sprintf(fn_buf, "/tmp/dump.txt.%d", os::current_process_id()); - heap_dump_file = fopen(fn_buf, "w"); - fileStream fstream(heap_dump_file); - out = &fstream; -#endif // SEND_HEAP_DUMP_TO_FILE - - RegionReachablePrinterClosure rcl(_prevMarkBitMap, out); - out->print_cr("--- ITERATING OVER REGIONS WITH PTAMS < TOP"); +void ConcurrentMark::print_reachable(bool use_prev_marking, const char* str) { + gclog_or_tty->print_cr("== Doing reachable object dump... "); + + if (G1PrintReachableBaseFile == NULL) { + gclog_or_tty->print_cr(" #### error: no base file defined"); + return; + } + + if (strlen(G1PrintReachableBaseFile) + 1 + strlen(str) > + (JVM_MAXPATHLEN - 1)) { + gclog_or_tty->print_cr(" #### error: file name too long"); + return; + } + + char file_name[JVM_MAXPATHLEN]; + sprintf(file_name, "%s.%s", G1PrintReachableBaseFile, str); + gclog_or_tty->print_cr(" dumping to file %s", file_name); + + fileStream fout(file_name); + if (!fout.is_open()) { + gclog_or_tty->print_cr(" #### error: could not open file"); + return; + } + + outputStream* out = &fout; + + CMBitMapRO* bitmap = NULL; + if (use_prev_marking) { + bitmap = _prevMarkBitMap; + } else { + bitmap = _nextMarkBitMap; + } + + out->print_cr("-- USING %s", (use_prev_marking) ? "PTAMS" : "NTAMS"); + out->cr(); + + RegionReachablePrinterClosure rcl(bitmap, out, use_prev_marking); + out->print_cr("--- ITERATING OVER REGIONS WITH TAMS < TOP"); + out->cr(); _g1h->heap_region_iterate(&rcl); - out->print_cr(""); - - ReachablePrinterClosure cl(_prevMarkBitMap, out); - out->print_cr("--- REACHABLE OBJECTS ON THE BITMAP"); - _prevMarkBitMap->iterate(&cl); - out->print_cr(""); - -#if SEND_HEAP_DUMP_TO_FILE - fclose(heap_dump_file); - heap_dump_file = NULL; -#endif // SEND_HEAP_DUMP_TO_FILE + out->cr(); + + ReachablePrinterClosure cl(bitmap, out, use_prev_marking); + out->print_cr("--- ITERATING OVER MARKED OBJECTS ON THE BITMAP"); + out->cr(); + bitmap->iterate(&cl); + out->cr(); + + gclog_or_tty->print_cr(" done"); } +#endif // PRODUCT + // This note is for drainAllSATBBuffers and the code in between. // In the future we could reuse a task to do this work during an // evacuation pause (since now tasks are not active and can be claimed diff -r 4926bf2d292f -r 29adffcb6a61 src/share/vm/gc_implementation/g1/concurrentMark.hpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp Thu Oct 29 08:49:31 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp Fri Oct 30 13:31:11 2009 -0400 @@ -612,10 +612,11 @@ // we do nothing. void markAndGrayObjectIfNecessary(oop p); - // This iterates over the bitmap of the previous marking and prints - // out all objects that are marked on the bitmap and indicates - // whether what they point to is also marked or not. - void print_prev_bitmap_reachable(); + // This iterates over the marking bitmap (either prev or next) and + // prints out all objects that are marked on the bitmap and indicates + // whether what they point to is also marked or not. It also iterates + // the objects over TAMS (either prev or next). + void print_reachable(bool use_prev_marking, const char* str); // Clear the next marking bitmap (will be called concurrently). void clearNextBitmap(); diff -r 4926bf2d292f -r 29adffcb6a61 src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Oct 29 08:49:31 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Oct 30 13:31:11 2009 -0400 @@ -2371,8 +2371,9 @@ gclog_or_tty->print_cr("Heap:"); print_on(gclog_or_tty, true /* extended */); gclog_or_tty->print_cr(""); - if (VerifyDuringGC && G1VerifyConcMarkPrintReachable) { - concurrent_mark()->print_prev_bitmap_reachable(); + if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) { + concurrent_mark()->print_reachable(use_prev_marking, + "failed-verification"); } gclog_or_tty->flush(); } @@ -3135,7 +3136,7 @@ _evac_failure_scan_stack->length() == 0, "Postcondition"); assert(!_drain_in_progress, "Postcondition"); - // Don't have to delete, since the scan stack is a resource object. + delete _evac_failure_scan_stack; _evac_failure_scan_stack = NULL; } diff -r 4926bf2d292f -r 29adffcb6a61 src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Oct 29 08:49:31 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Oct 30 13:31:11 2009 -0400 @@ -1516,7 +1516,8 @@ (end_time_sec - _recent_prev_end_times_for_all_gcs_sec->oldest()) * 1000.0; update_recent_gc_times(end_time_sec, elapsed_ms); _recent_avg_pause_time_ratio = _recent_gc_times_ms->sum()/interval_ms; - assert(recent_avg_pause_time_ratio() < 1.00, "All GC?"); + // using 1.01 to account for floating point inaccuracies + assert(recent_avg_pause_time_ratio() < 1.01, "All GC?"); } if (G1PolicyVerbose > 1) { diff -r 4926bf2d292f -r 29adffcb6a61 src/share/vm/gc_implementation/g1/g1_globals.hpp --- a/src/share/vm/gc_implementation/g1/g1_globals.hpp Thu Oct 29 08:49:31 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp Fri Oct 30 13:31:11 2009 -0400 @@ -55,8 +55,14 @@ develop(intx, G1MarkingVerboseLevel, 0, \ "Level (0-4) of verboseness of the marking code") \ \ - develop(bool, G1VerifyConcMarkPrintReachable, false, \ - "If conc mark verification fails, print reachable objects") \ + develop(bool, G1PrintReachableAtInitialMark, false, \ + "Reachable object dump at the initial mark pause") \ + \ + develop(bool, G1VerifyDuringGCPrintReachable, false, \ + "If conc mark verification fails, dump reachable objects") \ + \ + develop(ccstr, G1PrintReachableBaseFile, NULL, \ + "The base file name for the reachable object dumps") \ \ develop(bool, G1TraceMarkStackOverflow, false, \ "If true, extra debugging code for CM restart for ovflw.") \ diff -r 4926bf2d292f -r 29adffcb6a61 src/share/vm/gc_implementation/g1/sparsePRT.cpp --- a/src/share/vm/gc_implementation/g1/sparsePRT.cpp Thu Oct 29 08:49:31 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/sparsePRT.cpp Fri Oct 30 13:31:11 2009 -0400 @@ -135,7 +135,6 @@ _occupied_entries(0), _occupied_cards(0), _entries(NEW_C_HEAP_ARRAY(SparsePRTEntry, capacity)), _buckets(NEW_C_HEAP_ARRAY(int, capacity)), - _next_deleted(NULL), _deleted(false), _free_list(NullEntry), _free_region(0) { clear(); @@ -296,40 +295,6 @@ assert(e2->num_valid_cards() > 0, "Postcondition."); } -RSHashTable* RSHashTable::_head_deleted_list = NULL; - -void RSHashTable::add_to_deleted_list(RSHashTable* rsht) { - assert(!rsht->deleted(), "Should delete only once."); - rsht->set_deleted(true); - RSHashTable* hd = _head_deleted_list; - while (true) { - rsht->_next_deleted = hd; - RSHashTable* res = - (RSHashTable*) - Atomic::cmpxchg_ptr(rsht, &_head_deleted_list, hd); - if (res == hd) return; - else hd = res; - } -} - -RSHashTable* RSHashTable::get_from_deleted_list() { - RSHashTable* hd = _head_deleted_list; - while (hd != NULL) { - RSHashTable* next = hd->next_deleted(); - RSHashTable* res = - (RSHashTable*) - Atomic::cmpxchg_ptr(next, &_head_deleted_list, hd); - if (res == hd) { - hd->set_next_deleted(NULL); - hd->set_deleted(false); - return hd; - } else { - hd = res; - } - } - return NULL; -} - CardIdx_t /* RSHashTable:: */ RSHashTableIter::find_first_card_in_list() { CardIdx_t res; while (_bl_ind != RSHashTable::NullEntry) { @@ -442,15 +407,6 @@ sprt->cleanup(); sprt = get_from_expanded_list(); } - // Now delete all deleted RSHashTables. - RSHashTable* rsht = RSHashTable::get_from_deleted_list(); - while (rsht != NULL) { -#if SPARSE_PRT_VERBOSE - gclog_or_tty->print_cr("About to delete RSHT " PTR_FORMAT ".", rsht); -#endif - delete rsht; - rsht = RSHashTable::get_from_deleted_list(); - } } @@ -511,8 +467,10 @@ } void SparsePRT::cleanup() { - // Make sure that the current and next tables agree. (Another mechanism - // takes care of deleting now-unused tables.) + // Make sure that the current and next tables agree. + if (_cur != _next) { + delete _cur; + } _cur = _next; set_expanded(false); } @@ -535,7 +493,8 @@ _next->add_entry(e); } } - if (last != _cur) - RSHashTable::add_to_deleted_list(last); + if (last != _cur) { + delete last; + } add_to_expanded_list(this); } diff -r 4926bf2d292f -r 29adffcb6a61 src/share/vm/gc_implementation/g1/sparsePRT.hpp --- a/src/share/vm/gc_implementation/g1/sparsePRT.hpp Thu Oct 29 08:49:31 2009 -0700 +++ b/src/share/vm/gc_implementation/g1/sparsePRT.hpp Fri Oct 30 13:31:11 2009 -0400 @@ -102,13 +102,6 @@ int _free_region; int _free_list; - static RSHashTable* _head_deleted_list; - RSHashTable* _next_deleted; - RSHashTable* next_deleted() { return _next_deleted; } - void set_next_deleted(RSHashTable* rsht) { _next_deleted = rsht; } - bool _deleted; - void set_deleted(bool b) { _deleted = b; } - // Requires that the caller hold a lock preventing parallel modifying // operations, and that the the table be less than completely full. If // an entry for "region_ind" is already in the table, finds it and @@ -154,14 +147,10 @@ size_t occupied_entries() const { return _occupied_entries; } size_t occupied_cards() const { return _occupied_cards; } size_t mem_size() const; - bool deleted() { return _deleted; } SparsePRTEntry* entry(int i) const { return &_entries[i]; } void print(); - - static void add_to_deleted_list(RSHashTable* rsht); - static RSHashTable* get_from_deleted_list(); }; // ValueObj because will be embedded in HRRS iterator. diff -r 4926bf2d292f -r 29adffcb6a61 src/share/vm/services/heapDumper.cpp --- a/src/share/vm/services/heapDumper.cpp Thu Oct 29 08:49:31 2009 -0700 +++ b/src/share/vm/services/heapDumper.cpp Fri Oct 30 13:31:11 2009 -0400 @@ -1913,8 +1913,9 @@ if (use_default_filename) { char fn[32]; sprintf(fn, "java_pid%d", os::current_process_id()); - assert(strlen(base_path) + strlen(fn) < sizeof(base_path), "HeapDumpPath too long"); + assert(strlen(base_path) + strlen(fn) + strlen(".hprof") < sizeof(base_path), "HeapDumpPath too long"); strcat(base_path, fn); + strcat(base_path, ".hprof"); } assert(strlen(base_path) < sizeof(my_path), "Buffer too small"); strcpy(my_path, base_path); @@ -1927,8 +1928,6 @@ strcat(my_path, fn); } dump_file_seq++; // increment seq number for next time we dump - assert(strlen(".hprof") + strlen(my_path) < sizeof(my_path), "HeapDumpPath too long"); - strcat(my_path, ".hprof"); HeapDumper dumper(false /* no GC before heap dump */, true /* send to tty */);