diff --git a/src/share/vm/gc/parallel/parMarkBitMap.cpp b/src/share/vm/gc/parallel/parMarkBitMap.cpp --- a/src/share/vm/gc/parallel/parMarkBitMap.cpp +++ b/src/share/vm/gc/parallel/parMarkBitMap.cpp @@ -96,7 +96,7 @@ return false; } -size_t ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, oop end_obj) const +size_t ParMarkBitMap::live_words_in_range_helper(HeapWord* beg_addr, oop end_obj) const { assert(beg_addr <= (HeapWord*)end_obj, "bad range"); assert(is_marked(end_obj), "end_obj must be live"); @@ -117,6 +117,55 @@ return bits_to_words(live_bits); } +size_t ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, oop end_obj) const +{ + Thread* thread = Thread::current(); + HeapWord*& last_beg = thread->last_lwir_beg; + oop& last_obj = thread->last_lwir_obj; + size_t& last_ret = thread->last_lwir_ret; + + if (beg_addr == last_beg) { + if (end_obj > last_obj) { + last_ret = last_ret + live_words_in_range_helper((HeapWord*)last_obj, end_obj); + last_obj = end_obj; + } else if (end_obj < last_obj) { + if ((uint64_t)end_obj - (uint64_t)beg_addr > (uint64_t)last_obj - (uint64_t)end_obj) { + last_ret = last_ret - live_words_in_range_helper((HeapWord*)end_obj, last_obj); + } else { + last_ret = live_words_in_range_helper(beg_addr, end_obj); + } + last_obj = end_obj; + } + return last_ret; + } + + + assert(beg_addr <= (HeapWord*)end_obj, "bad range"); + assert(is_marked(end_obj), "end_obj must be live"); + + idx_t live_bits = 0; + + // The bitmap routines require the right boundary to be word-aligned. + const idx_t end_bit = addr_to_bit((HeapWord*)end_obj); + const idx_t range_end = BitMap::word_align_up(end_bit); + + idx_t beg_bit = find_obj_beg(addr_to_bit(beg_addr), range_end); + while (beg_bit < end_bit) { + idx_t tmp_end = find_obj_end(beg_bit, range_end); + assert(tmp_end < end_bit, "missing end bit"); + live_bits += tmp_end - beg_bit + 1; + beg_bit = find_obj_beg(tmp_end + 1, range_end); + } + //return bits_to_words(live_bits); + size_t r = bits_to_words(live_bits); + { + last_obj = end_obj; + last_ret = r; + last_beg = beg_addr; + } + return r; +} + ParMarkBitMap::IterationStatus ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure, idx_t range_beg, idx_t range_end) const diff --git a/src/share/vm/gc/parallel/parMarkBitMap.hpp b/src/share/vm/gc/parallel/parMarkBitMap.hpp --- a/src/share/vm/gc/parallel/parMarkBitMap.hpp +++ b/src/share/vm/gc/parallel/parMarkBitMap.hpp @@ -124,6 +124,7 @@ // the range are included in the result. The end of the range must be a live object, // which is the case when updating pointers. This allows a branch to be removed // from inside the loop. + size_t live_words_in_range_helper(HeapWord* beg_addr, oop end_obj) const; size_t live_words_in_range(HeapWord* beg_addr, oop end_obj) const; inline HeapWord* region_start() const; diff --git a/src/share/vm/gc/parallel/psParallelCompact.cpp b/src/share/vm/gc/parallel/psParallelCompact.cpp --- a/src/share/vm/gc/parallel/psParallelCompact.cpp +++ b/src/share/vm/gc/parallel/psParallelCompact.cpp @@ -1837,6 +1837,21 @@ DerivedPointerTable::set_active(false); #endif + + { + TraceTime tm("init thread for Incremental Query", print_phases()); + uint parallel_gc_threads = gc_task_manager()->workers(); + size_t bc = PSParallelCompact::summary_data().block_count(); + for (uint i=0; ithread(i); + t->last_lwir_beg = NULL; + } + } + // adjust_roots() updates Universe::_intArrayKlassObj which is // needed by the compaction for filling holes in the dense prefix. adjust_roots(); diff --git a/src/share/vm/runtime/thread.cpp b/src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp +++ b/src/share/vm/runtime/thread.cpp @@ -235,6 +235,10 @@ omInUseList = NULL; omInUseCount = 0; + last_lwir_beg = NULL; + last_lwir_obj = NULL; + last_lwir_ret = 0; + #ifdef ASSERT _visited_for_critical_count = false; #endif diff --git a/src/share/vm/runtime/thread.hpp b/src/share/vm/runtime/thread.hpp --- a/src/share/vm/runtime/thread.hpp +++ b/src/share/vm/runtime/thread.hpp @@ -289,6 +289,10 @@ ObjectMonitor* omInUseList; // SLL to track monitors in circulation int omInUseCount; // length of omInUseList + HeapWord* last_lwir_beg; + oop last_lwir_obj; + size_t last_lwir_ret; + #ifdef ASSERT private: bool _visited_for_critical_count;