Improve GSS reference processing.

Support the case where the reference object is in the free list space
and the referent object is in the bump pointer space at a bump pointer
space collection.

Bug: 11650816
Change-Id: If98b08edc9e37351c74ee07cb3f2d30c2b4d0056
diff --git a/runtime/gc/collector/semi_space.cc b/runtime/gc/collector/semi_space.cc
index b67bbb1..0413439 100644
--- a/runtime/gc/collector/semi_space.cc
+++ b/runtime/gc/collector/semi_space.cc
@@ -334,7 +334,8 @@
       accounting::RememberedSet* rem_set = heap_->FindRememberedSetFromSpace(space);
       if (kUseRememberedSet) {
         DCHECK(rem_set != nullptr);
-        rem_set->UpdateAndMarkReferences(MarkHeapReferenceCallback, from_space_, this);
+        rem_set->UpdateAndMarkReferences(MarkHeapReferenceCallback, DelayReferenceReferentCallback,
+                                         from_space_, this);
         if (kIsDebugBuild) {
           // Verify that there are no from-space references that
           // remain in the space, that is, the remembered set (and the
@@ -603,6 +604,11 @@
   reinterpret_cast<SemiSpace*>(arg)->MarkObject(obj_ptr);
 }
 
+void SemiSpace::DelayReferenceReferentCallback(mirror::Class* klass, mirror::Reference* ref,
+                                               void* arg) {
+  reinterpret_cast<SemiSpace*>(arg)->DelayReferenceReferent(klass, ref);
+}
+
 void SemiSpace::MarkRootCallback(Object** root, void* arg, uint32_t /*thread_id*/,
                                  RootType /*root_type*/) {
   auto ref = StackReference<mirror::Object>::FromMirrorPtr(*root);