diff -r a34b3268a14f src/share/vm/gc/parallel/parMarkBitMap.cpp
--- a/src/share/vm/gc/parallel/parMarkBitMap.cpp	Wed Dec 02 15:55:39 2015 -0800
+++ b/src/share/vm/gc/parallel/parMarkBitMap.cpp	Mon Dec 21 23:05:57 2015 +0800
@@ -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,39 @@
   return bits_to_words(live_bits);
 }
 
+size_t ParMarkBitMap::live_words_in_range_use_cache(HeapWord* beg_addr, oop end_obj) const 
+{
+  Thread* thread = Thread::current();
+  HeapWord* last_beg = thread->get_last_lwir_beg();
+  oop last_obj = thread->get_last_lwir_obj();
+  size_t last_ret = thread->get_last_lwir_ret();
+  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 (pointer_delta((HeapWord*)end_obj, (HeapWord*)beg_addr) > pointer_delta((HeapWord*)last_obj, (HeapWord*)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;      
+  }
+
+  update_live_words_in_range_cache(last_beg, last_obj, last_ret);
+  return last_ret;
+}
+
+size_t ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, oop end_obj) const
+{
+  //try reuse result in Thread-local cache
+  if (is_live_words_in_range_in_cache(beg_addr)) {
+    return live_words_in_range_use_cache(beg_addr, end_obj);
+  }
+  size_t ret = live_words_in_range_helper(beg_addr, end_obj);
+  update_live_words_in_range_cache(beg_addr, end_obj, ret);
+  return ret;
+}
+
 ParMarkBitMap::IterationStatus
 ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
                        idx_t range_beg, idx_t range_end) const
diff -r a34b3268a14f src/share/vm/gc/parallel/parMarkBitMap.hpp
--- a/src/share/vm/gc/parallel/parMarkBitMap.hpp	Wed Dec 02 15:55:39 2015 -0800
+++ b/src/share/vm/gc/parallel/parMarkBitMap.hpp	Mon Dec 21 23:05:57 2015 +0800
@@ -124,6 +124,19 @@
   // 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;
+  
+  inline bool is_live_words_in_range_in_cache(HeapWord* beg_addr) const {
+    return Thread::current()->get_last_lwir_beg() == beg_addr;
+  }
+  size_t live_words_in_range_use_cache(HeapWord* beg_addr, oop end_obj) const;
+  inline void update_live_words_in_range_cache(HeapWord* beg_addr, oop end_obj, size_t result) const {
+    Thread* thread = Thread::current();
+    thread->set_last_lwir_beg(beg_addr);
+    thread->set_last_lwir_obj(end_obj);
+    thread->set_last_lwir_ret(result);
+  }
+
   size_t live_words_in_range(HeapWord* beg_addr, oop end_obj) const;
 
   inline HeapWord* region_start() const;
diff -r a34b3268a14f src/share/vm/gc/parallel/psParallelCompact.cpp
--- a/src/share/vm/gc/parallel/psParallelCompact.cpp	Wed Dec 02 15:55:39 2015 -0800
+++ b/src/share/vm/gc/parallel/psParallelCompact.cpp	Mon Dec 21 23:05:57 2015 +0800
@@ -1837,6 +1837,21 @@
     DerivedPointerTable::set_active(false);
 #endif
 
+
+    //initialize live_words_in_range cache for all gc threads (including vm thread)
+    {
+      uint parallel_gc_threads = gc_task_manager()->workers();
+      size_t bc = PSParallelCompact::summary_data().block_count();
+      for (uint i=0; i<parallel_gc_threads+1; i++) {
+        Thread * t = NULL;
+        if (i == parallel_gc_threads)
+          t = Thread::current(); //vmthread
+        else
+          t = (Thread *)gc_task_manager()->thread(i);
+        t->set_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 -r a34b3268a14f src/share/vm/runtime/thread.cpp
--- a/src/share/vm/runtime/thread.cpp	Wed Dec 02 15:55:39 2015 -0800
+++ b/src/share/vm/runtime/thread.cpp	Mon Dec 21 23:05:57 2015 +0800
@@ -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 -r a34b3268a14f src/share/vm/runtime/thread.hpp
--- a/src/share/vm/runtime/thread.hpp	Wed Dec 02 15:55:39 2015 -0800
+++ b/src/share/vm/runtime/thread.hpp	Mon Dec 21 23:05:57 2015 +0800
@@ -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;
@@ -475,6 +479,16 @@
   // Apply "cf->do_code_blob" (if !NULL) to all code blobs active in frames
   virtual void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
 
+  // Full GC support, cache last query and result
+  HeapWord* get_last_lwir_beg() { return _last_lwir_beg; }
+  oop get_last_lwir_obj() { return _last_lwir_obj; }
+  size_t get_last_lwir_ret() { return _last_lwir_ret; }
+
+  void set_last_lwir_beg(HeapWord *new_beg) { _last_lwir_beg = new_beg; }
+  void set_last_lwir_obj(oop new_obj) { _last_lwir_obj = new_obj; }
+  void set_last_lwir_ret(size_t new_ret) { _last_lwir_ret = new_ret; }
+
+
   // Handles the parallel case for the method below.
  private:
   bool claim_oops_do_par_case(int collection_parity);
