< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp

Print this page
@@ -294,11 +294,11 @@
      return ShenandoahBarrierSet::resolve_forwarded(p);
    }
  
    assert(ShenandoahThreadLocalData::is_evac_allowed(thread), "must be enclosed in oom-evac scope");
  
-   size_t size = p->size();
+   size_t size = p->forward_safe_size();
  
    assert(!heap_region_containing(p)->is_humongous(), "never evacuate humongous objects");
  
    bool alloc_from_gclab = true;
    HeapWord* copy = nullptr;

@@ -329,15 +329,28 @@
      return ShenandoahBarrierSet::resolve_forwarded(p);
    }
  
    // Copy the object:
    Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(p), copy, size);
- 
-   // Try to install the new forwarding pointer.
    oop copy_val = cast_to_oop(copy);
-   ContinuationGCSupport::relativize_stack_chunk(copy_val);
+   if (UseCompactObjectHeaders) {
+     // The copy above is not atomic. Make sure we have seen the proper mark
+     // and re-install it into the copy, so that Klass* is guaranteed to be correct.
+     markWord mark = copy_val->mark();
+     if (!mark.is_marked()) {
+       copy_val->set_mark(mark);
+       ContinuationGCSupport::relativize_stack_chunk(copy_val);
+     } else {
+       // If we copied a mark-word that indicates 'forwarded' state, the object
+       // installation would not succeed. We cannot access Klass* anymore either.
+       // Skip the transformation.
+     }
+   } else {
+     ContinuationGCSupport::relativize_stack_chunk(copy_val);
+   }
  
+   // Try to install the new forwarding pointer.
    oop result = ShenandoahForwarding::try_update_forwardee(p, copy_val);
    if (result == copy_val) {
      // Successfully evacuated. Our copy is now the public one!
      shenandoah_assert_correct(nullptr, copy_val);
      return copy_val;

@@ -509,11 +522,11 @@
      assert (cs >= tams, "only objects past TAMS here: "   PTR_FORMAT " (" PTR_FORMAT ")", p2i(cs), p2i(tams));
      assert (cs < limit, "only objects below limit here: " PTR_FORMAT " (" PTR_FORMAT ")", p2i(cs), p2i(limit));
      oop obj = cast_to_oop(cs);
      assert(oopDesc::is_oop(obj), "sanity");
      assert(ctx->is_marked(obj), "object expected to be marked");
-     size_t size = obj->size();
+     size_t size = obj->forward_safe_size();
      cl->do_object(obj);
      cs += size;
    }
  }
  
< prev index next >