Merge
authorjwilhelm
Thu, 28 Jan 2016 19:30:39 +0100
changeset 35880 7b253cfc2eac
parent 35878 c22a2dd2416c (diff)
parent 35879 9892f53e92c9 (current diff)
child 35881 accf9644fb73
child 35882 98c7219214df
Merge
hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp
--- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp	Thu Jan 28 19:30:39 2016 +0100
@@ -110,7 +110,9 @@
 
 public:
 
-  HeapRegion* hr() const { return _hr; }
+  HeapRegion* hr() const {
+    return (HeapRegion*) OrderAccess::load_ptr_acquire(&_hr);
+  }
 
   jint occupied() const {
     // Overkill, but if we ever need it...
@@ -123,10 +125,12 @@
       set_next(NULL);
       set_prev(NULL);
     }
-    _hr = hr;
     _collision_list_next = NULL;
     _occupied = 0;
     _bm.clear();
+    // Make sure that the bitmap clearing above has been finished before publishing
+    // this PRT to concurrent threads.
+    OrderAccess::release_store_ptr(&_hr, hr);
   }
 
   void add_reference(OopOrNarrowOopStar from) {
@@ -357,7 +361,7 @@
   int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift);
 
   if (G1FromCardCache::contains_or_replace(tid, cur_hrm_ind, from_card)) {
-    assert(contains_reference(from), "We just added it!");
+    assert(contains_reference(from), "We just found " PTR_FORMAT " in the FromCardCache", p2i(from));
     return;
   }
 
@@ -367,7 +371,7 @@
 
   // If the region is already coarsened, return.
   if (_coarse_map.at(from_hrm_ind)) {
-    assert(contains_reference(from), "We just added it!");
+    assert(contains_reference(from), "We just found " PTR_FORMAT " in the Coarse table", p2i(from));
     return;
   }
 
@@ -388,7 +392,7 @@
              "Must be in range.");
       if (G1HRRSUseSparseTable &&
           _sparse_table.add_card(from_hrm_ind, card_index)) {
-        assert(contains_reference_locked(from), "We just added it!");
+        assert(contains_reference_locked(from), "We just added " PTR_FORMAT " to the Sparse table", p2i(from));
         return;
       }
 
@@ -438,7 +442,7 @@
   assert(prt != NULL, "Inv");
 
   prt->add_reference(from);
-  assert(contains_reference(from), "We just added it!");
+  assert(contains_reference(from), "We just added " PTR_FORMAT " to the PRT", p2i(from));
 }
 
 PerRegionTable*
--- a/hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp	Thu Jan 28 19:30:39 2016 +0100
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/parallel/parMarkBitMap.hpp"
+#include "gc/parallel/psCompactionManager.inline.hpp"
 #include "gc/parallel/psParallelCompact.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.inline.hpp"
@@ -96,7 +97,20 @@
   return false;
 }
 
-size_t ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, oop end_obj) const
+inline bool
+ParMarkBitMap::is_live_words_in_range_in_cache(ParCompactionManager* cm, HeapWord* beg_addr) const {
+  return cm->last_query_begin() == beg_addr;
+}
+
+inline void
+ParMarkBitMap::update_live_words_in_range_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj, size_t result) const {
+  cm->set_last_query_begin(beg_addr);
+  cm->set_last_query_object(end_obj);
+  cm->set_last_query_return(result);
+}
+
+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 +131,42 @@
   return bits_to_words(live_bits);
 }
 
+size_t
+ParMarkBitMap::live_words_in_range_use_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const
+{
+  HeapWord* last_beg = cm->last_query_begin();
+  oop last_obj = cm->last_query_object();
+  size_t last_ret = cm->last_query_return();
+  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) {
+    // The cached value is for an object that is to the left (lower address) of the current
+    // end_obj. Calculate back from that cached value.
+    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(cm, last_beg, last_obj, last_ret);
+  return last_ret;
+}
+
+size_t
+ParMarkBitMap::live_words_in_range(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const
+{
+  // Try to reuse result from ParCompactionManager cache first.
+  if (is_live_words_in_range_in_cache(cm, beg_addr)) {
+    return live_words_in_range_use_cache(cm, beg_addr, end_obj);
+  }
+  size_t ret = live_words_in_range_helper(beg_addr, end_obj);
+  update_live_words_in_range_cache(cm, beg_addr, end_obj, ret);
+  return ret;
+}
+
 ParMarkBitMap::IterationStatus
 ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
                        idx_t range_beg, idx_t range_end) const
--- a/hotspot/src/share/vm/gc/parallel/parMarkBitMap.hpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/gc/parallel/parMarkBitMap.hpp	Thu Jan 28 19:30:39 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
 
 class ParMarkBitMapClosure;
 class PSVirtualSpace;
+class ParCompactionManager;
 
 class ParMarkBitMap: public CHeapObj<mtGC>
 {
@@ -124,7 +125,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(HeapWord* beg_addr, oop end_obj) const;
+  size_t live_words_in_range(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const;
 
   inline HeapWord* region_start() const;
   inline HeapWord* region_end() const;
@@ -167,6 +168,12 @@
 #endif  // #ifdef ASSERT
 
 private:
+  size_t live_words_in_range_helper(HeapWord* beg_addr, oop end_obj) const;
+
+  bool is_live_words_in_range_in_cache(ParCompactionManager* cm, HeapWord* beg_addr) const;
+  size_t live_words_in_range_use_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const;
+  void update_live_words_in_range_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj, size_t result) const;
+
   // Each bit in the bitmap represents one unit of 'object granularity.' Objects
   // are double-word aligned in 32-bit VMs, but not in 64-bit VMs, so the 32-bit
   // granularity is 2, 64-bit is 1.
--- a/hotspot/src/share/vm/gc/parallel/psCompactionManager.cpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/gc/parallel/psCompactionManager.cpp	Thu Jan 28 19:30:39 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -68,6 +68,8 @@
 
   marking_stack()->initialize();
   _objarray_stack.initialize();
+
+  reset_bitmap_query_cache();
 }
 
 ParCompactionManager::~ParCompactionManager() {
@@ -124,6 +126,13 @@
     "Not initialized?");
 }
 
+void ParCompactionManager::reset_all_bitmap_query_caches() {
+  uint parallel_gc_threads = PSParallelCompact::gc_task_manager()->workers();
+  for (uint i=0; i<=parallel_gc_threads; i++) {
+    _manager_array[i]->reset_bitmap_query_cache();
+  }
+}
+
 int ParCompactionManager::pop_recycled_stack_index() {
   assert(_recycled_bottom <= _recycled_top, "list is empty");
   // Get the next available index
--- a/hotspot/src/share/vm/gc/parallel/psCompactionManager.hpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/gc/parallel/psCompactionManager.hpp	Thu Jan 28 19:30:39 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -109,6 +109,10 @@
 
   Action _action;
 
+  HeapWord* _last_query_beg;
+  oop _last_query_obj;
+  size_t _last_query_ret;
+
   static PSOldGen* old_gen()             { return _old_gen; }
   static ObjectStartArray* start_array() { return _start_array; }
   static OopTaskQueueSet* stack_array()  { return _stack_array; }
@@ -127,9 +131,26 @@
   // marking stack and overflow stack directly.
 
  public:
+  void reset_bitmap_query_cache() {
+    _last_query_beg = NULL;
+    _last_query_obj = NULL;
+    _last_query_ret = 0;
+  }
+
   Action action() { return _action; }
   void set_action(Action v) { _action = v; }
 
+  // Bitmap query support, cache last query and result
+  HeapWord* last_query_begin() { return _last_query_beg; }
+  oop last_query_object() { return _last_query_obj; }
+  size_t last_query_return() { return _last_query_ret; }
+
+  void set_last_query_begin(HeapWord *new_beg) { _last_query_beg = new_beg; }
+  void set_last_query_object(oop new_obj) { _last_query_obj = new_obj; }
+  void set_last_query_return(size_t new_ret) { _last_query_ret = new_ret; }
+
+  static void reset_all_bitmap_query_caches();
+
   RegionTaskQueue* region_stack()                { return _region_stack; }
   void set_region_stack(RegionTaskQueue* v)       { _region_stack = v; }
 
--- a/hotspot/src/share/vm/gc/parallel/psCompactionManager.inline.hpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/gc/parallel/psCompactionManager.inline.hpp	Thu Jan 28 19:30:39 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -144,7 +144,7 @@
 }
 
 inline void ParCompactionManager::update_contents(oop obj) {
-  obj->pc_update_contents();
+  obj->pc_update_contents(this);
 }
 
 #endif // SHARE_VM_GC_PARALLEL_PSCOMPACTIONMANAGER_INLINE_HPP
--- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp	Thu Jan 28 19:30:39 2016 +0100
@@ -751,7 +751,7 @@
   return true;
 }
 
-HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr) {
+HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr, ParCompactionManager* cm) {
   assert(addr != NULL, "Should detect NULL oop earlier");
   assert(ParallelScavengeHeap::heap()->is_in(addr), "not in heap");
   assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "not marked");
@@ -788,7 +788,7 @@
   const size_t block_offset = addr_to_block_ptr(addr)->offset();
 
   const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap();
-  const size_t live = bitmap->live_words_in_range(search_start, oop(addr));
+  const size_t live = bitmap->live_words_in_range(cm, search_start, oop(addr));
   result += block_offset + live;
   DEBUG_ONLY(PSParallelCompact::check_new_location(addr, result));
   return result;
@@ -825,11 +825,9 @@
 
 bool PSParallelCompact::IsAliveClosure::do_object_b(oop p) { return mark_bitmap()->is_marked(p); }
 
-PSParallelCompact::AdjustPointerClosure PSParallelCompact::_adjust_pointer_closure;
-PSParallelCompact::AdjustKlassClosure PSParallelCompact::_adjust_klass_closure;
-
 void PSParallelCompact::AdjustKlassClosure::do_klass(Klass* klass) {
-  klass->oops_do(&PSParallelCompact::_adjust_pointer_closure);
+  PSParallelCompact::AdjustPointerClosure closure(_cm);
+  klass->oops_do(&closure);
 }
 
 void PSParallelCompact::post_initialize() {
@@ -977,6 +975,8 @@
 
   // Have worker threads release resources the next time they run a task.
   gc_task_manager()->release_all_resources();
+
+  ParCompactionManager::reset_all_bitmap_query_caches();
 }
 
 void PSParallelCompact::post_compact()
@@ -1801,7 +1801,7 @@
 
     // adjust_roots() updates Universe::_intArrayKlassObj which is
     // needed by the compaction for filling holes in the dense prefix.
-    adjust_roots();
+    adjust_roots(vmthread_cm);
 
     compaction_start.update();
     compact();
@@ -2142,39 +2142,42 @@
 };
 static PSAlwaysTrueClosure always_true;
 
-void PSParallelCompact::adjust_roots() {
+void PSParallelCompact::adjust_roots(ParCompactionManager* cm) {
   // Adjust the pointers to reflect the new locations
   GCTraceTime(Trace, gc, phases) tm("Adjust Roots", &_gc_timer);
 
   // Need new claim bits when tracing through and adjusting pointers.
   ClassLoaderDataGraph::clear_claimed_marks();
 
+  PSParallelCompact::AdjustPointerClosure oop_closure(cm);
+  PSParallelCompact::AdjustKlassClosure klass_closure(cm);
+
   // General strong roots.
-  Universe::oops_do(adjust_pointer_closure());
-  JNIHandles::oops_do(adjust_pointer_closure());   // Global (strong) JNI handles
-  CLDToOopClosure adjust_from_cld(adjust_pointer_closure());
-  Threads::oops_do(adjust_pointer_closure(), &adjust_from_cld, NULL);
-  ObjectSynchronizer::oops_do(adjust_pointer_closure());
-  FlatProfiler::oops_do(adjust_pointer_closure());
-  Management::oops_do(adjust_pointer_closure());
-  JvmtiExport::oops_do(adjust_pointer_closure());
-  SystemDictionary::oops_do(adjust_pointer_closure());
-  ClassLoaderDataGraph::oops_do(adjust_pointer_closure(), adjust_klass_closure(), true);
+  Universe::oops_do(&oop_closure);
+  JNIHandles::oops_do(&oop_closure);   // Global (strong) JNI handles
+  CLDToOopClosure adjust_from_cld(&oop_closure);
+  Threads::oops_do(&oop_closure, &adjust_from_cld, NULL);
+  ObjectSynchronizer::oops_do(&oop_closure);
+  FlatProfiler::oops_do(&oop_closure);
+  Management::oops_do(&oop_closure);
+  JvmtiExport::oops_do(&oop_closure);
+  SystemDictionary::oops_do(&oop_closure);
+  ClassLoaderDataGraph::oops_do(&oop_closure, &klass_closure, true);
 
   // Now adjust pointers in remaining weak roots.  (All of which should
   // have been cleared if they pointed to non-surviving objects.)
   // Global (weak) JNI handles
-  JNIHandles::weak_oops_do(&always_true, adjust_pointer_closure());
-
-  CodeBlobToOopClosure adjust_from_blobs(adjust_pointer_closure(), CodeBlobToOopClosure::FixRelocations);
+  JNIHandles::weak_oops_do(&always_true, &oop_closure);
+
+  CodeBlobToOopClosure adjust_from_blobs(&oop_closure, CodeBlobToOopClosure::FixRelocations);
   CodeCache::blobs_do(&adjust_from_blobs);
-  StringTable::oops_do(adjust_pointer_closure());
-  ref_processor()->weak_oops_do(adjust_pointer_closure());
+  StringTable::oops_do(&oop_closure);
+  ref_processor()->weak_oops_do(&oop_closure);
   // Roots were visited so references into the young gen in roots
   // may have been scanned.  Process them also.
   // Should the reference processor have a span that excludes
   // young gen objects?
-  PSScavenge::reference_processor()->weak_oops_do(adjust_pointer_closure());
+  PSScavenge::reference_processor()->weak_oops_do(&oop_closure);
 }
 
 // Helper class to print 8 region numbers per line and then print the total at the end.
@@ -3062,18 +3065,20 @@
   update_state(words);
 }
 
-void InstanceKlass::oop_pc_update_pointers(oop obj) {
-  oop_oop_iterate_oop_maps<true>(obj, PSParallelCompact::adjust_pointer_closure());
+void InstanceKlass::oop_pc_update_pointers(oop obj, ParCompactionManager* cm) {
+  PSParallelCompact::AdjustPointerClosure closure(cm);
+  oop_oop_iterate_oop_maps<true>(obj, &closure);
 }
 
-void InstanceMirrorKlass::oop_pc_update_pointers(oop obj) {
-  InstanceKlass::oop_pc_update_pointers(obj);
-
-  oop_oop_iterate_statics<true>(obj, PSParallelCompact::adjust_pointer_closure());
+void InstanceMirrorKlass::oop_pc_update_pointers(oop obj, ParCompactionManager* cm) {
+  InstanceKlass::oop_pc_update_pointers(obj, cm);
+
+  PSParallelCompact::AdjustPointerClosure closure(cm);
+  oop_oop_iterate_statics<true>(obj, &closure);
 }
 
-void InstanceClassLoaderKlass::oop_pc_update_pointers(oop obj) {
-  InstanceKlass::oop_pc_update_pointers(obj);
+void InstanceClassLoaderKlass::oop_pc_update_pointers(oop obj, ParCompactionManager* cm) {
+  InstanceKlass::oop_pc_update_pointers(obj, cm);
 }
 
 #ifdef ASSERT
@@ -3092,33 +3097,34 @@
 #endif
 
 template <class T>
-static void oop_pc_update_pointers_specialized(oop obj) {
+static void oop_pc_update_pointers_specialized(oop obj, ParCompactionManager* cm) {
   T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
-  PSParallelCompact::adjust_pointer(referent_addr);
+  PSParallelCompact::adjust_pointer(referent_addr, cm);
   T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
-  PSParallelCompact::adjust_pointer(next_addr);
+  PSParallelCompact::adjust_pointer(next_addr, cm);
   T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
-  PSParallelCompact::adjust_pointer(discovered_addr);
+  PSParallelCompact::adjust_pointer(discovered_addr, cm);
   debug_only(trace_reference_gc("InstanceRefKlass::oop_update_ptrs", obj,
                                 referent_addr, next_addr, discovered_addr);)
 }
 
-void InstanceRefKlass::oop_pc_update_pointers(oop obj) {
-  InstanceKlass::oop_pc_update_pointers(obj);
+void InstanceRefKlass::oop_pc_update_pointers(oop obj, ParCompactionManager* cm) {
+  InstanceKlass::oop_pc_update_pointers(obj, cm);
 
   if (UseCompressedOops) {
-    oop_pc_update_pointers_specialized<narrowOop>(obj);
+    oop_pc_update_pointers_specialized<narrowOop>(obj, cm);
   } else {
-    oop_pc_update_pointers_specialized<oop>(obj);
+    oop_pc_update_pointers_specialized<oop>(obj, cm);
   }
 }
 
-void ObjArrayKlass::oop_pc_update_pointers(oop obj) {
+void ObjArrayKlass::oop_pc_update_pointers(oop obj, ParCompactionManager* cm) {
   assert(obj->is_objArray(), "obj must be obj array");
-  oop_oop_iterate_elements<true>(objArrayOop(obj), PSParallelCompact::adjust_pointer_closure());
+  PSParallelCompact::AdjustPointerClosure closure(cm);
+  oop_oop_iterate_elements<true>(objArrayOop(obj), &closure);
 }
 
-void TypeArrayKlass::oop_pc_update_pointers(oop obj) {
+void TypeArrayKlass::oop_pc_update_pointers(oop obj, ParCompactionManager* cm) {
   assert(obj->is_typeArray(),"must be a type array");
 }
 
@@ -3128,7 +3134,7 @@
   assert(bitmap()->obj_size(addr) == words, "bad size");
 
   _source = addr;
-  assert(PSParallelCompact::summary_data().calc_new_pointer(source()) ==
+  assert(PSParallelCompact::summary_data().calc_new_pointer(source(), compaction_manager()) ==
          destination(), "wrong destination");
 
   if (words > words_remaining()) {
--- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.hpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.hpp	Thu Jan 28 19:30:39 2016 +0100
@@ -451,10 +451,10 @@
   HeapWord* partial_obj_end(size_t region_idx) const;
 
   // Return the location of the object after compaction.
-  HeapWord* calc_new_pointer(HeapWord* addr);
+  HeapWord* calc_new_pointer(HeapWord* addr, ParCompactionManager* cm);
 
-  HeapWord* calc_new_pointer(oop p) {
-    return calc_new_pointer((HeapWord*) p);
+  HeapWord* calc_new_pointer(oop p, ParCompactionManager* cm) {
+    return calc_new_pointer((HeapWord*) p, cm);
   }
 
 #ifdef  ASSERT
@@ -937,17 +937,29 @@
 
   class AdjustPointerClosure: public ExtendedOopClosure {
    public:
+    AdjustPointerClosure(ParCompactionManager* cm) {
+      assert(cm != NULL, "associate ParCompactionManage should not be NULL");
+      _cm = cm;
+    }
     template <typename T> void do_oop_nv(T* p);
     virtual void do_oop(oop* p);
     virtual void do_oop(narrowOop* p);
 
     // This closure provides its own oop verification code.
     debug_only(virtual bool should_verify_oops() { return false; })
+   private:
+    ParCompactionManager* _cm;
   };
 
   class AdjustKlassClosure : public KlassClosure {
    public:
+    AdjustKlassClosure(ParCompactionManager* cm) {
+      assert(cm != NULL, "associate ParCompactionManage should not be NULL");
+      _cm = cm;
+    }
     void do_klass(Klass* klass);
+   private:
+    ParCompactionManager* _cm;
   };
 
   friend class AdjustPointerClosure;
@@ -966,8 +978,6 @@
   static ParallelCompactData  _summary_data;
   static IsAliveClosure       _is_alive_closure;
   static SpaceInfo            _space_info[last_space_id];
-  static AdjustPointerClosure _adjust_pointer_closure;
-  static AdjustKlassClosure   _adjust_klass_closure;
 
   // Reference processing (used in ...follow_contents)
   static ReferenceProcessor*  _ref_processor;
@@ -1063,7 +1073,7 @@
   static void summary_phase(ParCompactionManager* cm, bool maximum_compaction);
 
   // Adjust addresses in roots.  Does not adjust addresses in heap.
-  static void adjust_roots();
+  static void adjust_roots(ParCompactionManager* cm);
 
   DEBUG_ONLY(static void write_block_fill_histogram();)
 
@@ -1109,10 +1119,6 @@
   static bool initialize();
 
   // Closure accessors
-  static PSParallelCompact::AdjustPointerClosure* adjust_pointer_closure() {
-    return &_adjust_pointer_closure;
-  }
-  static KlassClosure* adjust_klass_closure()      { return (KlassClosure*)&_adjust_klass_closure; }
   static BoolObjectClosure* is_alive_closure()     { return (BoolObjectClosure*)&_is_alive_closure; }
 
   // Public accessors
@@ -1127,7 +1133,7 @@
   static inline bool mark_obj(oop obj);
   static inline bool is_marked(oop obj);
 
-  template <class T> static inline void adjust_pointer(T* p);
+  template <class T> static inline void adjust_pointer(T* p, ParCompactionManager* cm);
 
   // Compaction support.
   // Return true if p is in the range [beg_addr, end_addr).
--- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.inline.hpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.inline.hpp	Thu Jan 28 19:30:39 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,13 +42,13 @@
 }
 
 template <class T>
-inline void PSParallelCompact::adjust_pointer(T* p) {
+inline void PSParallelCompact::adjust_pointer(T* p, ParCompactionManager* cm) {
   T heap_oop = oopDesc::load_heap_oop(p);
   if (!oopDesc::is_null(heap_oop)) {
     oop obj     = oopDesc::decode_heap_oop_not_null(heap_oop);
     assert(ParallelScavengeHeap::heap()->is_in(obj), "should be in heap");
 
-    oop new_obj = (oop)summary_data().calc_new_pointer(obj);
+    oop new_obj = (oop)summary_data().calc_new_pointer(obj, cm);
     assert(new_obj != NULL,                    // is forwarding ptr?
            "should be forwarded");
     // Just always do the update unconditionally?
@@ -62,7 +62,7 @@
 
 template <typename T>
 void PSParallelCompact::AdjustPointerClosure::do_oop_nv(T* p) {
-  adjust_pointer(p);
+  adjust_pointer(p, _cm);
 }
 
 inline void PSParallelCompact::AdjustPointerClosure::do_oop(oop* p)       { do_oop_nv(p); }
--- a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp	Thu Jan 28 19:30:39 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -55,7 +55,7 @@
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
   // Parallel Compact
   void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
-  void oop_pc_update_pointers(oop obj);
+  void oop_pc_update_pointers(oop obj, ParCompactionManager* cm);
 #endif
 
   // Oop fields (and metadata) iterators
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Thu Jan 28 19:30:39 2016 +0100
@@ -1050,7 +1050,7 @@
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
   // Parallel Compact
   void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
-  void oop_pc_update_pointers(oop obj);
+  void oop_pc_update_pointers(oop obj, ParCompactionManager* cm);
 #endif
 
   // Oop fields (and metadata) iterators
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp	Thu Jan 28 19:30:39 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -96,7 +96,7 @@
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
   // Parallel Compact
   void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
-  void oop_pc_update_pointers(oop obj);
+  void oop_pc_update_pointers(oop obj, ParCompactionManager* cm);
 #endif
 
   // Oop fields (and metadata) iterators
--- a/hotspot/src/share/vm/oops/instanceRefKlass.hpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.hpp	Thu Jan 28 19:30:39 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -65,7 +65,7 @@
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
   // Parallel Compact
   void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
-  void oop_pc_update_pointers(oop obj);
+  void oop_pc_update_pointers(oop obj, ParCompactionManager* cm);
 #endif
 
   // Oop fields (and metadata) iterators
--- a/hotspot/src/share/vm/oops/klass.hpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/oops/klass.hpp	Thu Jan 28 19:30:39 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -578,7 +578,7 @@
   virtual void oop_ps_push_contents(  oop obj, PSPromotionManager* pm)   = 0;
   // Parallel Compact
   virtual void oop_pc_follow_contents(oop obj, ParCompactionManager* cm) = 0;
-  virtual void oop_pc_update_pointers(oop obj) = 0;
+  virtual void oop_pc_update_pointers(oop obj, ParCompactionManager* cm) = 0;
 #endif
 
   // Iterators specialized to particular subtypes
--- a/hotspot/src/share/vm/oops/objArrayKlass.hpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/oops/objArrayKlass.hpp	Thu Jan 28 19:30:39 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -116,7 +116,7 @@
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
   // Parallel Compact
   void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
-  void oop_pc_update_pointers(oop obj);
+  void oop_pc_update_pointers(oop obj, ParCompactionManager* cm);
 #endif
 
   // Oop fields (and metadata) iterators
--- a/hotspot/src/share/vm/oops/oop.hpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/oops/oop.hpp	Thu Jan 28 19:30:39 2016 +0100
@@ -330,8 +330,8 @@
   inline int  ms_adjust_pointers();
 #if INCLUDE_ALL_GCS
   // Parallel Compact
-  inline void pc_follow_contents(ParCompactionManager* pc);
-  inline void pc_update_contents();
+  inline void pc_follow_contents(ParCompactionManager* cm);
+  inline void pc_update_contents(ParCompactionManager* cm);
   // Parallel Scavenge
   inline void ps_push_contents(PSPromotionManager* pm);
 #endif
--- a/hotspot/src/share/vm/oops/oop.inline.hpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp	Thu Jan 28 19:30:39 2016 +0100
@@ -650,11 +650,11 @@
   klass()->oop_pc_follow_contents(this, cm);
 }
 
-void oopDesc::pc_update_contents() {
+void oopDesc::pc_update_contents(ParCompactionManager* cm) {
   Klass* k = klass();
   if (!k->is_typeArray_klass()) {
     // It might contain oops beyond the header, so take the virtual call.
-    k->oop_pc_update_pointers(this);
+    k->oop_pc_update_pointers(this, cm);
   }
   // Else skip it.  The TypeArrayKlass in the header never needs scavenging.
 }
--- a/hotspot/src/share/vm/oops/typeArrayKlass.hpp	Fri Jan 22 06:13:52 2016 -0500
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.hpp	Thu Jan 28 19:30:39 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -81,7 +81,7 @@
   void oop_ps_push_contents(  oop obj, PSPromotionManager* pm);
   // Parallel Compact
   void oop_pc_follow_contents(oop obj, ParCompactionManager* cm);
-  void oop_pc_update_pointers(oop obj);
+  void oop_pc_update_pointers(oop obj, ParCompactionManager* cm);
 #endif
 
   // Oop iterators. Since there are no oops in TypeArrayKlasses,