hotspot/src/share/vm/memory/referenceProcessor.cpp
changeset 360 21d113ecbf6a
parent 178 3f20890fb323
child 670 ddf3e9583f2f
child 1374 4c24294029a9
--- a/hotspot/src/share/vm/memory/referenceProcessor.cpp	Fri Apr 11 09:56:35 2008 -0400
+++ b/hotspot/src/share/vm/memory/referenceProcessor.cpp	Sun Apr 13 17:43:42 2008 -0400
@@ -28,16 +28,32 @@
 // List of discovered references.
 class DiscoveredList {
 public:
-         DiscoveredList() : _head(NULL), _len(0) { }
-  oop    head() const           { return _head; }
-  oop*   head_ptr()             { return &_head; }
-  void   set_head(oop o)        { _head = o; }
-  bool   empty() const          { return _head == ReferenceProcessor::_sentinelRef; }
+  DiscoveredList() : _len(0), _compressed_head(0), _oop_head(NULL) { }
+  oop head() const     {
+     return UseCompressedOops ?  oopDesc::decode_heap_oop_not_null(_compressed_head) :
+                                _oop_head;
+  }
+  HeapWord* adr_head() {
+    return UseCompressedOops ? (HeapWord*)&_compressed_head :
+                               (HeapWord*)&_oop_head;
+  }
+  void   set_head(oop o) {
+    if (UseCompressedOops) {
+      // Must compress the head ptr.
+      _compressed_head = oopDesc::encode_heap_oop_not_null(o);
+    } else {
+      _oop_head = o;
+    }
+  }
+  bool   empty() const          { return head() == ReferenceProcessor::sentinel_ref(); }
   size_t length()               { return _len; }
   void   set_length(size_t len) { _len = len; }
 private:
+  // Set value depending on UseCompressedOops. This could be a template class
+  // but then we have to fix all the instantiations and declarations that use this class.
+  oop       _oop_head;
+  narrowOop _compressed_head;
   size_t _len;
-  oop   _head;
 };
 
 oop  ReferenceProcessor::_sentinelRef = NULL;
@@ -49,11 +65,11 @@
 }
 
 void ReferenceProcessor::init_statics() {
-  assert(_sentinelRef == NULL, "should be initialized precsiely once");
+  assert(_sentinelRef == NULL, "should be initialized precisely once");
   EXCEPTION_MARK;
   _sentinelRef = instanceKlass::cast(
-                   SystemDictionary::object_klass())->
-                     allocate_permanent_instance(THREAD);
+                    SystemDictionary::reference_klass())->
+                      allocate_permanent_instance(THREAD);
 
   // Initialize the master soft ref clock.
   java_lang_ref_SoftReference::set_clock(os::javaTimeMillis());
@@ -69,15 +85,13 @@
             "Unrecongnized RefDiscoveryPolicy");
 }
 
-
-ReferenceProcessor* ReferenceProcessor::create_ref_processor(
-    MemRegion          span,
-    bool               atomic_discovery,
-    bool               mt_discovery,
-    BoolObjectClosure* is_alive_non_header,
-    int                parallel_gc_threads,
-    bool               mt_processing)
-{
+ReferenceProcessor*
+ReferenceProcessor::create_ref_processor(MemRegion          span,
+                                         bool               atomic_discovery,
+                                         bool               mt_discovery,
+                                         BoolObjectClosure* is_alive_non_header,
+                                         int                parallel_gc_threads,
+                                         bool               mt_processing) {
   int mt_degree = 1;
   if (parallel_gc_threads > 1) {
     mt_degree = parallel_gc_threads;
@@ -93,10 +107,11 @@
   return rp;
 }
 
-
 ReferenceProcessor::ReferenceProcessor(MemRegion span,
-  bool atomic_discovery, bool mt_discovery, int mt_degree,
-  bool mt_processing) :
+                                       bool      atomic_discovery,
+                                       bool      mt_discovery,
+                                       int       mt_degree,
+                                       bool      mt_processing) :
   _discovering_refs(false),
   _enqueuing_is_done(false),
   _is_alive_non_header(NULL),
@@ -114,10 +129,10 @@
   _discoveredWeakRefs    = &_discoveredSoftRefs[_num_q];
   _discoveredFinalRefs   = &_discoveredWeakRefs[_num_q];
   _discoveredPhantomRefs = &_discoveredFinalRefs[_num_q];
-  assert(_sentinelRef != NULL, "_sentinelRef is NULL");
+  assert(sentinel_ref() != NULL, "_sentinelRef is NULL");
   // Initialized all entries to _sentinelRef
   for (int i = 0; i < _num_q * subclasses_of_ref; i++) {
-        _discoveredSoftRefs[i].set_head(_sentinelRef);
+        _discoveredSoftRefs[i].set_head(sentinel_ref());
     _discoveredSoftRefs[i].set_length(0);
   }
 }
@@ -134,16 +149,19 @@
 
 void ReferenceProcessor::weak_oops_do(OopClosure* f) {
   for (int i = 0; i < _num_q * subclasses_of_ref; i++) {
-    f->do_oop(_discoveredSoftRefs[i].head_ptr());
+    if (UseCompressedOops) {
+      f->do_oop((narrowOop*)_discoveredSoftRefs[i].adr_head());
+    } else {
+      f->do_oop((oop*)_discoveredSoftRefs[i].adr_head());
+    }
   }
 }
 
 void ReferenceProcessor::oops_do(OopClosure* f) {
-  f->do_oop(&_sentinelRef);
+  f->do_oop(adr_sentinel_ref());
 }
 
-void ReferenceProcessor::update_soft_ref_master_clock()
-{
+void ReferenceProcessor::update_soft_ref_master_clock() {
   // Update (advance) the soft ref master clock field. This must be done
   // after processing the soft ref list.
   jlong now = os::javaTimeMillis();
@@ -164,9 +182,7 @@
   // past clock value.
 }
 
-
-void
-ReferenceProcessor::process_discovered_references(
+void ReferenceProcessor::process_discovered_references(
   ReferencePolicy*             policy,
   BoolObjectClosure*           is_alive,
   OopClosure*                  keep_alive,
@@ -223,15 +239,13 @@
   }
 }
 
-
 #ifndef PRODUCT
 // Calculate the number of jni handles.
-unsigned int ReferenceProcessor::count_jni_refs()
-{
+uint ReferenceProcessor::count_jni_refs() {
   class AlwaysAliveClosure: public BoolObjectClosure {
   public:
-    bool do_object_b(oop obj) { return true; }
-    void do_object(oop obj) { assert(false, "Don't call"); }
+    virtual bool do_object_b(oop obj) { return true; }
+    virtual void do_object(oop obj) { assert(false, "Don't call"); }
   };
 
   class CountHandleClosure: public OopClosure {
@@ -239,9 +253,8 @@
     int _count;
   public:
     CountHandleClosure(): _count(0) {}
-    void do_oop(oop* unused) {
-      _count++;
-    }
+    void do_oop(oop* unused)       { _count++; }
+    void do_oop(narrowOop* unused) { ShouldNotReachHere(); }
     int count() { return _count; }
   };
   CountHandleClosure global_handle_count;
@@ -262,36 +275,48 @@
 #endif
   JNIHandles::weak_oops_do(is_alive, keep_alive);
   // Finally remember to keep sentinel around
-  keep_alive->do_oop(&_sentinelRef);
+  keep_alive->do_oop(adr_sentinel_ref());
   complete_gc->do_void();
 }
 
-bool ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) {
-  NOT_PRODUCT(verify_ok_to_handle_reflists());
+
+template <class T>
+static bool enqueue_discovered_ref_helper(ReferenceProcessor* ref,
+                                          AbstractRefProcTaskExecutor* task_executor) {
+
   // Remember old value of pending references list
-  oop* pending_list_addr = java_lang_ref_Reference::pending_list_addr();
-  oop old_pending_list_value = *pending_list_addr;
+  T* pending_list_addr = (T*)java_lang_ref_Reference::pending_list_addr();
+  T old_pending_list_value = *pending_list_addr;
 
   // Enqueue references that are not made active again, and
   // clear the decks for the next collection (cycle).
-  enqueue_discovered_reflists(pending_list_addr, task_executor);
+  ref->enqueue_discovered_reflists((HeapWord*)pending_list_addr, task_executor);
   // Do the oop-check on pending_list_addr missed in
   // enqueue_discovered_reflist. We should probably
   // do a raw oop_check so that future such idempotent
   // oop_stores relying on the oop-check side-effect
   // may be elided automatically and safely without
   // affecting correctness.
-  oop_store(pending_list_addr, *(pending_list_addr));
+  oop_store(pending_list_addr, oopDesc::load_decode_heap_oop(pending_list_addr));
 
   // Stop treating discovered references specially.
-  disable_discovery();
+  ref->disable_discovery();
 
   // Return true if new pending references were added
   return old_pending_list_value != *pending_list_addr;
 }
 
+bool ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) {
+  NOT_PRODUCT(verify_ok_to_handle_reflists());
+  if (UseCompressedOops) {
+    return enqueue_discovered_ref_helper<narrowOop>(this, task_executor);
+  } else {
+    return enqueue_discovered_ref_helper<oop>(this, task_executor);
+  }
+}
+
 void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list,
-  oop* pending_list_addr) {
+                                                    HeapWord* pending_list_addr) {
   // Given a list of refs linked through the "discovered" field
   // (java.lang.ref.Reference.discovered) chain them through the
   // "next" field (java.lang.ref.Reference.next) and prepend
@@ -305,19 +330,19 @@
   // the next field and clearing it (except for the last
   // non-sentinel object which is treated specially to avoid
   // confusion with an active reference).
-  while (obj != _sentinelRef) {
+  while (obj != sentinel_ref()) {
     assert(obj->is_instanceRef(), "should be reference object");
     oop next = java_lang_ref_Reference::discovered(obj);
     if (TraceReferenceGC && PrintGCDetails) {
-      gclog_or_tty->print_cr("  obj " INTPTR_FORMAT "/next " INTPTR_FORMAT,
-                             (oopDesc*) obj, (oopDesc*) next);
+      gclog_or_tty->print_cr("        obj " INTPTR_FORMAT "/next " INTPTR_FORMAT,
+                             obj, next);
     }
-    assert(*java_lang_ref_Reference::next_addr(obj) == NULL,
-      "The reference should not be enqueued");
-    if (next == _sentinelRef) {  // obj is last
+    assert(java_lang_ref_Reference::next(obj) == NULL,
+           "The reference should not be enqueued");
+    if (next == sentinel_ref()) {  // obj is last
       // Swap refs_list into pendling_list_addr and
       // set obj's next to what we read from pending_list_addr.
-      oop old = (oop)Atomic::xchg_ptr(refs_list.head(), pending_list_addr);
+      oop old = oopDesc::atomic_exchange_oop(refs_list.head(), pending_list_addr);
       // Need oop_check on pending_list_addr above;
       // see special oop-check code at the end of
       // enqueue_discovered_reflists() further below.
@@ -341,15 +366,14 @@
 public:
   RefProcEnqueueTask(ReferenceProcessor& ref_processor,
                      DiscoveredList      discovered_refs[],
-                     oop*                pending_list_addr,
+                     HeapWord*           pending_list_addr,
                      oop                 sentinel_ref,
                      int                 n_queues)
     : EnqueueTask(ref_processor, discovered_refs,
                   pending_list_addr, sentinel_ref, n_queues)
   { }
 
-  virtual void work(unsigned int work_id)
-  {
+  virtual void work(unsigned int work_id) {
     assert(work_id < (unsigned int)_ref_processor.num_q(), "Index out-of-bounds");
     // Simplest first cut: static partitioning.
     int index = work_id;
@@ -363,18 +387,18 @@
 };
 
 // Enqueue references that are not made active again
-void ReferenceProcessor::enqueue_discovered_reflists(oop* pending_list_addr,
+void ReferenceProcessor::enqueue_discovered_reflists(HeapWord* pending_list_addr,
   AbstractRefProcTaskExecutor* task_executor) {
   if (_processing_is_mt && task_executor != NULL) {
     // Parallel code
     RefProcEnqueueTask tsk(*this, _discoveredSoftRefs,
-                           pending_list_addr, _sentinelRef, _num_q);
+                           pending_list_addr, sentinel_ref(), _num_q);
     task_executor->execute(tsk);
   } else {
     // Serial code: call the parent class's implementation
     for (int i = 0; i < _num_q * subclasses_of_ref; i++) {
       enqueue_discovered_reflist(_discoveredSoftRefs[i], pending_list_addr);
-      _discoveredSoftRefs[i].set_head(_sentinelRef);
+      _discoveredSoftRefs[i].set_head(sentinel_ref());
       _discoveredSoftRefs[i].set_length(0);
     }
   }
@@ -388,14 +412,13 @@
                                 BoolObjectClosure* is_alive);
 
   // End Of List.
-  inline bool has_next() const
-  { return _next != ReferenceProcessor::_sentinelRef; }
+  inline bool has_next() const { return _next != ReferenceProcessor::sentinel_ref(); }
 
   // Get oop to the Reference object.
-  inline oop  obj() const { return _ref; }
+  inline oop obj() const { return _ref; }
 
   // Get oop to the referent object.
-  inline oop  referent() const { return _referent; }
+  inline oop referent() const { return _referent; }
 
   // Returns true if referent is alive.
   inline bool is_referent_alive() const;
@@ -417,13 +440,26 @@
   inline void make_active() { java_lang_ref_Reference::set_next(_ref, NULL); }
 
   // Make the referent alive.
-  inline void make_referent_alive() { _keep_alive->do_oop(_referent_addr); }
+  inline void make_referent_alive() {
+    if (UseCompressedOops) {
+      _keep_alive->do_oop((narrowOop*)_referent_addr);
+    } else {
+      _keep_alive->do_oop((oop*)_referent_addr);
+    }
+  }
 
   // Update the discovered field.
-  inline void update_discovered() { _keep_alive->do_oop(_prev_next); }
+  inline void update_discovered() {
+    // First _prev_next ref actually points into DiscoveredList (gross).
+    if (UseCompressedOops) {
+      _keep_alive->do_oop((narrowOop*)_prev_next);
+    } else {
+      _keep_alive->do_oop((oop*)_prev_next);
+    }
+  }
 
   // NULL out referent pointer.
-  inline void clear_referent() { *_referent_addr = NULL; }
+  inline void clear_referent() { oop_store_raw(_referent_addr, NULL); }
 
   // Statistics
   NOT_PRODUCT(
@@ -436,11 +472,11 @@
 
 private:
   DiscoveredList&    _refs_list;
-  oop*               _prev_next;
+  HeapWord*          _prev_next;
   oop                _ref;
-  oop*               _discovered_addr;
+  HeapWord*          _discovered_addr;
   oop                _next;
-  oop*               _referent_addr;
+  HeapWord*          _referent_addr;
   oop                _referent;
   OopClosure*        _keep_alive;
   BoolObjectClosure* _is_alive;
@@ -457,7 +493,7 @@
                                                       OopClosure*        keep_alive,
                                                       BoolObjectClosure* is_alive)
   : _refs_list(refs_list),
-    _prev_next(refs_list.head_ptr()),
+    _prev_next(refs_list.adr_head()),
     _ref(refs_list.head()),
 #ifdef ASSERT
     _first_seen(refs_list.head()),
@@ -471,19 +507,18 @@
     _is_alive(is_alive)
 { }
 
-inline bool DiscoveredListIterator::is_referent_alive() const
-{
+inline bool DiscoveredListIterator::is_referent_alive() const {
   return _is_alive->do_object_b(_referent);
 }
 
-inline void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent))
-{
+inline void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) {
   _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref);
-  assert(_discovered_addr && (*_discovered_addr)->is_oop_or_null(),
+  oop discovered = java_lang_ref_Reference::discovered(_ref);
+  assert(_discovered_addr && discovered->is_oop_or_null(),
          "discovered field is bad");
-  _next = *_discovered_addr;
+  _next = discovered;
   _referent_addr = java_lang_ref_Reference::referent_addr(_ref);
-  _referent = *_referent_addr;
+  _referent = java_lang_ref_Reference::referent(_ref);
   assert(Universe::heap()->is_in_reserved_or_null(_referent),
          "Wrong oop found in java.lang.Reference object");
   assert(allow_null_referent ?
@@ -492,32 +527,32 @@
          "bad referent");
 }
 
-inline void DiscoveredListIterator::next()
-{
+inline void DiscoveredListIterator::next() {
   _prev_next = _discovered_addr;
   move_to_next();
 }
 
-inline void DiscoveredListIterator::remove()
-{
+inline void DiscoveredListIterator::remove() {
   assert(_ref->is_oop(), "Dropping a bad reference");
-  // Clear the discovered_addr field so that the object does
-  // not look like it has been discovered.
-  *_discovered_addr = NULL;
-  // Remove Reference object from list.
-  *_prev_next = _next;
+  oop_store_raw(_discovered_addr, NULL);
+  // First _prev_next ref actually points into DiscoveredList (gross).
+  if (UseCompressedOops) {
+    // Remove Reference object from list.
+    oopDesc::encode_store_heap_oop_not_null((narrowOop*)_prev_next, _next);
+  } else {
+    // Remove Reference object from list.
+    oopDesc::store_heap_oop((oop*)_prev_next, _next);
+  }
   NOT_PRODUCT(_removed++);
   move_to_next();
 }
 
-inline void DiscoveredListIterator::move_to_next()
-{
+inline void DiscoveredListIterator::move_to_next() {
   _ref = _next;
   assert(_ref != _first_seen, "cyclic ref_list found");
   NOT_PRODUCT(_processed++);
 }
 
-
 // NOTE: process_phase*() are largely similar, and at a high level
 // merely iterate over the extant list applying a predicate to
 // each of its elements and possibly removing that element from the
@@ -531,13 +566,13 @@
 // referents are not alive, but that should be kept alive for policy reasons.
 // Keep alive the transitive closure of all such referents.
 void
-ReferenceProcessor::process_phase1(DiscoveredList&    refs_list_addr,
+ReferenceProcessor::process_phase1(DiscoveredList&    refs_list,
                                    ReferencePolicy*   policy,
                                    BoolObjectClosure* is_alive,
                                    OopClosure*        keep_alive,
                                    VoidClosure*       complete_gc) {
   assert(policy != NULL, "Must have a non-NULL policy");
-  DiscoveredListIterator iter(refs_list_addr, keep_alive, is_alive);
+  DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
   // Decide which softly reachable refs should be kept alive.
   while (iter.has_next()) {
     iter.load_ptrs(DEBUG_ONLY(!discovery_is_atomic() /* allow_null_referent */));
@@ -545,7 +580,7 @@
     if (referent_is_dead && !policy->should_clear_reference(iter.obj())) {
       if (TraceReferenceGC) {
         gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s"  ") by policy",
-                               (address)iter.obj(), iter.obj()->blueprint()->internal_name());
+                               iter.obj(), iter.obj()->blueprint()->internal_name());
       }
       // Make the Reference object active again
       iter.make_active();
@@ -570,20 +605,19 @@
 // Traverse the list and remove any Refs that are not active, or
 // whose referents are either alive or NULL.
 void
-ReferenceProcessor::pp2_work(DiscoveredList&    refs_list_addr,
+ReferenceProcessor::pp2_work(DiscoveredList&    refs_list,
                              BoolObjectClosure* is_alive,
-                             OopClosure*        keep_alive)
-{
+                             OopClosure*        keep_alive) {
   assert(discovery_is_atomic(), "Error");
-  DiscoveredListIterator iter(refs_list_addr, keep_alive, is_alive);
+  DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
   while (iter.has_next()) {
     iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
-    DEBUG_ONLY(oop* next_addr = java_lang_ref_Reference::next_addr(iter.obj());)
-    assert(*next_addr == NULL, "Should not discover inactive Reference");
+    DEBUG_ONLY(oop next = java_lang_ref_Reference::next(iter.obj());)
+    assert(next == NULL, "Should not discover inactive Reference");
     if (iter.is_referent_alive()) {
       if (TraceReferenceGC) {
         gclog_or_tty->print_cr("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)",
-                               (address)iter.obj(), iter.obj()->blueprint()->internal_name());
+                               iter.obj(), iter.obj()->blueprint()->internal_name());
       }
       // The referent is reachable after all.
       // Update the referent pointer as necessary: Note that this
@@ -605,25 +639,28 @@
 }
 
 void
-ReferenceProcessor::pp2_work_concurrent_discovery(
-  DiscoveredList&    refs_list_addr,
-  BoolObjectClosure* is_alive,
-  OopClosure*        keep_alive,
-  VoidClosure*       complete_gc)
-{
+ReferenceProcessor::pp2_work_concurrent_discovery(DiscoveredList&    refs_list,
+                                                  BoolObjectClosure* is_alive,
+                                                  OopClosure*        keep_alive,
+                                                  VoidClosure*       complete_gc) {
   assert(!discovery_is_atomic(), "Error");
-  DiscoveredListIterator iter(refs_list_addr, keep_alive, is_alive);
+  DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
   while (iter.has_next()) {
     iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
-    oop* next_addr = java_lang_ref_Reference::next_addr(iter.obj());
+    HeapWord* next_addr = java_lang_ref_Reference::next_addr(iter.obj());
+    oop next = java_lang_ref_Reference::next(iter.obj());
     if ((iter.referent() == NULL || iter.is_referent_alive() ||
-         *next_addr != NULL)) {
-      assert((*next_addr)->is_oop_or_null(), "bad next field");
+         next != NULL)) {
+      assert(next->is_oop_or_null(), "bad next field");
       // Remove Reference object from list
       iter.remove();
       // Trace the cohorts
       iter.make_referent_alive();
-      keep_alive->do_oop(next_addr);
+      if (UseCompressedOops) {
+        keep_alive->do_oop((narrowOop*)next_addr);
+      } else {
+        keep_alive->do_oop((oop*)next_addr);
+      }
     } else {
       iter.next();
     }
@@ -639,15 +676,15 @@
 }
 
 // Traverse the list and process the referents, by either
-// either clearing them or keeping them (and their reachable
+// clearing them or keeping them (and their reachable
 // closure) alive.
 void
-ReferenceProcessor::process_phase3(DiscoveredList&    refs_list_addr,
+ReferenceProcessor::process_phase3(DiscoveredList&    refs_list,
                                    bool               clear_referent,
                                    BoolObjectClosure* is_alive,
                                    OopClosure*        keep_alive,
                                    VoidClosure*       complete_gc) {
-  DiscoveredListIterator iter(refs_list_addr, keep_alive, is_alive);
+  DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
   while (iter.has_next()) {
     iter.update_discovered();
     iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
@@ -661,7 +698,7 @@
     if (TraceReferenceGC) {
       gclog_or_tty->print_cr("Adding %sreference (" INTPTR_FORMAT ": %s) as pending",
                              clear_referent ? "cleared " : "",
-                             (address)iter.obj(), iter.obj()->blueprint()->internal_name());
+                             iter.obj(), iter.obj()->blueprint()->internal_name());
     }
     assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference");
     // If discovery is concurrent, we may have objects with null referents,
@@ -679,15 +716,15 @@
 }
 
 void
-ReferenceProcessor::abandon_partial_discovered_list(DiscoveredList& ref_list) {
-  oop obj = ref_list.head();
-  while (obj != _sentinelRef) {
-    oop* discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
-    obj = *discovered_addr;
-    *discovered_addr = NULL;
+ReferenceProcessor::abandon_partial_discovered_list(DiscoveredList& refs_list) {
+  oop obj = refs_list.head();
+  while (obj != sentinel_ref()) {
+    oop discovered = java_lang_ref_Reference::discovered(obj);
+    java_lang_ref_Reference::set_discovered_raw(obj, NULL);
+    obj = discovered;
   }
-  ref_list.set_head(_sentinelRef);
-  ref_list.set_length(0);
+  refs_list.set_head(sentinel_ref());
+  refs_list.set_length(0);
 }
 
 void
@@ -777,7 +814,7 @@
         // find an element to split the list on
         for (size_t j = 0; j < refs_to_move; ++j) {
           move_tail = new_head;
-          new_head = *java_lang_ref_Reference::discovered_addr(new_head);
+          new_head = java_lang_ref_Reference::discovered(new_head);
         }
         java_lang_ref_Reference::set_discovered(move_tail, ref_lists[to_idx].head());
         ref_lists[to_idx].set_head(move_head);
@@ -875,17 +912,17 @@
   size_t length = refs_list.length();
   while (iter.has_next()) {
     iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
-    oop* next_addr = java_lang_ref_Reference::next_addr(iter.obj());
-    assert((*next_addr)->is_oop_or_null(), "bad next field");
+    oop next = java_lang_ref_Reference::next(iter.obj());
+    assert(next->is_oop_or_null(), "bad next field");
     // If referent has been cleared or Reference is not active,
     // drop it.
-    if (iter.referent() == NULL || *next_addr != NULL) {
+    if (iter.referent() == NULL || next != NULL) {
       debug_only(
         if (PrintGCDetails && TraceReferenceGC) {
           gclog_or_tty->print_cr("clean_up_discovered_list: Dropping Reference: "
             INTPTR_FORMAT " with next field: " INTPTR_FORMAT
             " and referent: " INTPTR_FORMAT,
-            (address)iter.obj(), (address)*next_addr, (address)iter.referent());
+            iter.obj(), next, iter.referent());
         }
       )
       // Remove Reference object from list
@@ -950,18 +987,21 @@
   return list;
 }
 
-inline void ReferenceProcessor::add_to_discovered_list_mt(DiscoveredList& list,
-  oop obj, oop* discovered_addr) {
+inline void
+ReferenceProcessor::add_to_discovered_list_mt(DiscoveredList& refs_list,
+                                              oop             obj,
+                                              HeapWord*       discovered_addr) {
   assert(_discovery_is_mt, "!_discovery_is_mt should have been handled by caller");
   // First we must make sure this object is only enqueued once. CAS in a non null
   // discovered_addr.
-  oop retest = (oop)Atomic::cmpxchg_ptr(list.head(), discovered_addr, NULL);
+  oop retest = oopDesc::atomic_compare_exchange_oop(refs_list.head(), discovered_addr,
+                                                    NULL);
   if (retest == NULL) {
     // This thread just won the right to enqueue the object.
     // We have separate lists for enqueueing so no synchronization
     // is necessary.
-    list.set_head(obj);
-    list.set_length(list.length() + 1);
+    refs_list.set_head(obj);
+    refs_list.set_length(refs_list.length() + 1);
   } else {
     // If retest was non NULL, another thread beat us to it:
     // The reference has already been discovered...
@@ -972,7 +1012,6 @@
   }
 }
 
-
 // We mention two of several possible choices here:
 // #0: if the reference object is not in the "originating generation"
 //     (or part of the heap being collected, indicated by our "span"
@@ -1006,8 +1045,8 @@
     return false;
   }
   // We only enqueue active references.
-  oop* next_addr = java_lang_ref_Reference::next_addr(obj);
-  if (*next_addr != NULL) {
+  oop next = java_lang_ref_Reference::next(obj);
+  if (next != NULL) {
     return false;
   }
 
@@ -1034,14 +1073,14 @@
     }
   }
 
-  oop* discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
-  assert(discovered_addr != NULL && (*discovered_addr)->is_oop_or_null(),
-         "bad discovered field");
-  if (*discovered_addr != NULL) {
+  HeapWord* discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
+  oop  discovered = java_lang_ref_Reference::discovered(obj);
+  assert(discovered->is_oop_or_null(), "bad discovered field");
+  if (discovered != NULL) {
     // The reference has already been discovered...
     if (TraceReferenceGC) {
       gclog_or_tty->print_cr("Already enqueued reference (" INTPTR_FORMAT ": %s)",
-                             (oopDesc*)obj, obj->blueprint()->internal_name());
+                             obj, obj->blueprint()->internal_name());
     }
     if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
       // assumes that an object is not processed twice;
@@ -1088,7 +1127,7 @@
   if (_discovery_is_mt) {
     add_to_discovered_list_mt(*list, obj, discovered_addr);
   } else {
-    *discovered_addr = list->head();
+    oop_store_raw(discovered_addr, list->head());
     list->set_head(obj);
     list->set_length(list->length() + 1);
   }
@@ -1106,7 +1145,7 @@
     oop referent = java_lang_ref_Reference::referent(obj);
     if (PrintGCDetails) {
       gclog_or_tty->print_cr("Enqueued reference (" INTPTR_FORMAT ": %s)",
-                             (oopDesc*) obj, obj->blueprint()->internal_name());
+                             obj, obj->blueprint()->internal_name());
     }
     assert(referent->is_oop(), "Enqueued a bad referent");
   }
@@ -1181,17 +1220,20 @@
 // are not active (have a non-NULL next field). NOTE: For this to work
 // correctly, refs discovery can not be happening concurrently with this
 // step.
-void ReferenceProcessor::preclean_discovered_reflist(
-  DiscoveredList& refs_list, BoolObjectClosure* is_alive,
-  OopClosure* keep_alive, VoidClosure* complete_gc, YieldClosure* yield) {
-
+void
+ReferenceProcessor::preclean_discovered_reflist(DiscoveredList&    refs_list,
+                                                BoolObjectClosure* is_alive,
+                                                OopClosure*        keep_alive,
+                                                VoidClosure*       complete_gc,
+                                                YieldClosure*      yield) {
   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
   size_t length = refs_list.length();
   while (iter.has_next()) {
     iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
-    oop* next_addr = java_lang_ref_Reference::next_addr(iter.obj());
+    oop obj = iter.obj();
+    oop next = java_lang_ref_Reference::next(obj);
     if (iter.referent() == NULL || iter.is_referent_alive() ||
-        *next_addr != NULL) {
+        next != NULL) {
       // The referent has been cleared, or is alive, or the Reference is not
       // active; we need to trace and mark its cohort.
       if (TraceReferenceGC) {
@@ -1203,7 +1245,13 @@
       --length;
       // Keep alive its cohort.
       iter.make_referent_alive();
-      keep_alive->do_oop(next_addr);
+      if (UseCompressedOops) {
+        narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr(obj);
+        keep_alive->do_oop(next_addr);
+      } else {
+        oop* next_addr = (oop*)java_lang_ref_Reference::next_addr(obj);
+        keep_alive->do_oop(next_addr);
+      }
     } else {
       iter.next();
     }
@@ -1241,7 +1289,7 @@
 #endif
 
 void ReferenceProcessor::verify() {
-  guarantee(_sentinelRef != NULL && _sentinelRef->is_oop(), "Lost _sentinelRef");
+  guarantee(sentinel_ref() != NULL && sentinel_ref()->is_oop(), "Lost _sentinelRef");
 }
 
 #ifndef PRODUCT
@@ -1249,12 +1297,12 @@
   guarantee(!_discovering_refs, "Discovering refs?");
   for (int i = 0; i < _num_q * subclasses_of_ref; i++) {
     oop obj = _discoveredSoftRefs[i].head();
-    while (obj != _sentinelRef) {
+    while (obj != sentinel_ref()) {
       oop next = java_lang_ref_Reference::discovered(obj);
       java_lang_ref_Reference::set_discovered(obj, (oop) NULL);
       obj = next;
     }
-    _discoveredSoftRefs[i].set_head(_sentinelRef);
+    _discoveredSoftRefs[i].set_head(sentinel_ref());
     _discoveredSoftRefs[i].set_length(0);
   }
 }