diff options
| -rw-r--r-- | runtime/gc/collector/concurrent_copying-inl.h | 2 | ||||
| -rw-r--r-- | runtime/gc/collector/concurrent_copying.cc | 14 | ||||
| -rw-r--r-- | runtime/gc/collector/concurrent_copying.h | 5 |
3 files changed, 16 insertions, 5 deletions
diff --git a/runtime/gc/collector/concurrent_copying-inl.h b/runtime/gc/collector/concurrent_copying-inl.h index 1f06f15ae6..3503973321 100644 --- a/runtime/gc/collector/concurrent_copying-inl.h +++ b/runtime/gc/collector/concurrent_copying-inl.h @@ -130,7 +130,7 @@ inline mirror::Object* ConcurrentCopying::Mark(mirror::Object* from_ref, mirror::Object* to_ref = GetFwdPtr(from_ref); if (to_ref == nullptr) { // It isn't marked yet. Mark it by copying it to the to-space. - to_ref = Copy(from_ref); + to_ref = Copy(from_ref, holder, offset); } DCHECK(region_space_->IsInToSpace(to_ref) || heap_->non_moving_space_->HasAddress(to_ref)) << "from_ref=" << from_ref << " to_ref=" << to_ref; diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc index 9c3ce0b413..b3780e6be4 100644 --- a/runtime/gc/collector/concurrent_copying.cc +++ b/runtime/gc/collector/concurrent_copying.cc @@ -2218,8 +2218,16 @@ mirror::Object* ConcurrentCopying::AllocateInSkippedBlock(size_t alloc_size) { return reinterpret_cast<mirror::Object*>(addr); } -mirror::Object* ConcurrentCopying::Copy(mirror::Object* from_ref) { +mirror::Object* ConcurrentCopying::Copy(mirror::Object* from_ref, + mirror::Object* holder, + MemberOffset offset) { DCHECK(region_space_->IsInFromSpace(from_ref)); + // If the class pointer is null, the object is invalid. This could occur for a dangling pointer + // from a previous GC that is either inside or outside the allocated region. + mirror::Class* klass = from_ref->GetClass<kVerifyNone, kWithoutReadBarrier>(); + if (UNLIKELY(klass == nullptr)) { + heap_->GetVerification()->LogHeapCorruption(holder, offset, from_ref, /* fatal */ true); + } // There must not be a read barrier to avoid nested RB that might violate the to-space invariant. // Note that from_ref is a from space ref so the SizeOf() call will access the from-space meta // objects, but it's ok and necessary. @@ -2274,7 +2282,7 @@ mirror::Object* ConcurrentCopying::Copy(mirror::Object* from_ref) { DCHECK(to_ref != nullptr); // Copy the object excluding the lock word since that is handled in the loop. - to_ref->SetClass(from_ref->GetClass<kVerifyNone, kWithoutReadBarrier>()); + to_ref->SetClass(klass); const size_t kObjectHeaderSize = sizeof(mirror::Object); DCHECK_GE(obj_size, kObjectHeaderSize); static_assert(kObjectHeaderSize == sizeof(mirror::HeapReference<mirror::Class>) + @@ -2482,7 +2490,7 @@ mirror::Object* ConcurrentCopying::MarkNonMoving(mirror::Object* ref, if (is_los && !IsAligned<kPageSize>(ref)) { // Ref is a large object that is not aligned, it must be heap corruption. Dump data before // AtomicSetReadBarrierState since it will fault if the address is not valid. - heap_->GetVerification()->LogHeapCorruption(ref, offset, holder, /* fatal */ true); + heap_->GetVerification()->LogHeapCorruption(holder, offset, ref, /* fatal */ true); } // Not marked or on the allocation stack. Try to mark it. // This may or may not succeed, which is ok. diff --git a/runtime/gc/collector/concurrent_copying.h b/runtime/gc/collector/concurrent_copying.h index d8dc9f6b2b..ae5d068d71 100644 --- a/runtime/gc/collector/concurrent_copying.h +++ b/runtime/gc/collector/concurrent_copying.h @@ -133,7 +133,10 @@ class ConcurrentCopying : public GarbageCollector { private: void PushOntoMarkStack(mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!mark_stack_lock_); - mirror::Object* Copy(mirror::Object* from_ref) REQUIRES_SHARED(Locks::mutator_lock_) + mirror::Object* Copy(mirror::Object* from_ref, + mirror::Object* holder, + MemberOffset offset) + REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!mark_stack_lock_, !skipped_blocks_lock_, !immune_gray_stack_lock_); void Scan(mirror::Object* to_ref) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!mark_stack_lock_); |