summaryrefslogtreecommitdiffstats
path: root/runtime/gc
diff options
context:
space:
mode:
authorHiroshi Yamauchi <yamauchi@google.com>2015-04-23 16:12:40 -0700
committerHiroshi Yamauchi <yamauchi@google.com>2015-04-23 21:11:40 -0700
commit60f63f53c01cb38ca18a815603282e802a6cf918 (patch)
tree4f18427401ead0c790e926672957189a0c0a39eb /runtime/gc
parent633a37ece49c5afcf3fa9a89692f07d19c56229b (diff)
downloadart-60f63f53c01cb38ca18a815603282e802a6cf918.zip
art-60f63f53c01cb38ca18a815603282e802a6cf918.tar.gz
art-60f63f53c01cb38ca18a815603282e802a6cf918.tar.bz2
Use the lock word bits for Baker-style read barrier.
This enables the standard object header to be used with the Baker-style read barrier. Bug: 19355854 Bug: 12687968 Change-Id: Ie552b6e1dfe30e96cb1d0895bd0dff25f9d7d015
Diffstat (limited to 'runtime/gc')
-rw-r--r--runtime/gc/collector/concurrent_copying.cc33
-rw-r--r--runtime/gc/collector/semi_space-inl.h4
-rw-r--r--runtime/gc/reference_queue.cc4
3 files changed, 29 insertions, 12 deletions
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index eabb1c2..26f349a 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -718,6 +718,7 @@ bool ConcurrentCopying::ProcessMarkStack() {
// Leave References gray so that GetReferent() will trigger RB.
CHECK(to_ref->AsReference()->IsEnqueued()) << "Left unenqueued ref gray " << to_ref;
} else {
+#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
if (kUseBakerReadBarrier) {
if (region_space_->IsInToSpace(to_ref)) {
// If to-space, change from gray to white.
@@ -739,6 +740,9 @@ bool ConcurrentCopying::ProcessMarkStack() {
CHECK(to_ref->GetReadBarrierPointer() == ReadBarrier::BlackPtr());
}
}
+#else
+ DCHECK(!kUseBakerReadBarrier);
+#endif
}
if (ReadBarrier::kEnableToSpaceInvariantChecks || kIsDebugBuild) {
ConcurrentCopyingAssertToSpaceInvariantObjectVisitor visitor(this);
@@ -815,7 +819,7 @@ class ConcurrentCopyingClearBlackPtrsVisitor {
DCHECK(obj != nullptr);
DCHECK(collector_->heap_->GetMarkBitmap()->Test(obj)) << obj;
DCHECK_EQ(obj->GetReadBarrierPointer(), ReadBarrier::BlackPtr()) << obj;
- obj->SetReadBarrierPointer(ReadBarrier::WhitePtr());
+ obj->AtomicSetReadBarrierPointer(ReadBarrier::BlackPtr(), ReadBarrier::WhitePtr());
DCHECK_EQ(obj->GetReadBarrierPointer(), ReadBarrier::WhitePtr()) << obj;
}
@@ -963,7 +967,8 @@ class ConcurrentCopyingComputeUnevacFromSpaceLiveRatioVisitor {
if (kUseBakerReadBarrier) {
DCHECK_EQ(ref->GetReadBarrierPointer(), ReadBarrier::BlackPtr()) << ref;
// Clear the black ptr.
- ref->SetReadBarrierPointer(ReadBarrier::WhitePtr());
+ ref->AtomicSetReadBarrierPointer(ReadBarrier::BlackPtr(), ReadBarrier::WhitePtr());
+ DCHECK_EQ(ref->GetReadBarrierPointer(), ReadBarrier::WhitePtr()) << ref;
}
size_t obj_size = ref->SizeOf();
size_t alloc_size = RoundUp(obj_size, space::RegionSpace::kAlignment);
@@ -1330,10 +1335,6 @@ mirror::Object* ConcurrentCopying::Copy(mirror::Object* from_ref) {
while (true) {
// Copy the object. TODO: copy only the lockword in the second iteration and on?
memcpy(to_ref, from_ref, obj_size);
- // Set the gray ptr.
- if (kUseBakerReadBarrier) {
- to_ref->SetReadBarrierPointer(ReadBarrier::GrayPtr());
- }
LockWord old_lock_word = to_ref->GetLockWord(false);
@@ -1378,6 +1379,11 @@ mirror::Object* ConcurrentCopying::Copy(mirror::Object* from_ref) {
return to_ref;
}
+ // Set the gray ptr.
+ if (kUseBakerReadBarrier) {
+ to_ref->SetReadBarrierPointer(ReadBarrier::GrayPtr());
+ }
+
LockWord new_lock_word = LockWord::FromForwardingAddress(reinterpret_cast<size_t>(to_ref));
// Try to atomically write the fwd ptr.
@@ -1484,6 +1490,21 @@ mirror::Object* ConcurrentCopying::Mark(mirror::Object* from_ref) {
}
DCHECK(from_ref != nullptr);
DCHECK(heap_->collector_type_ == kCollectorTypeCC);
+ if (kUseBakerReadBarrier && !is_active_) {
+ // In the lock word forward address state, the read barrier bits
+ // in the lock word are part of the stored forwarding address and
+ // invalid. This is usually OK as the from-space copy of objects
+ // aren't accessed by mutators due to the to-space
+ // invariant. However, during the dex2oat image writing relocation
+ // and the zygote compaction, objects can be in the forward
+ // address state (to store the forward/relocation addresses) and
+ // they can still be accessed and the invalid read barrier bits
+ // are consulted. If they look like gray but aren't really, the
+ // read barriers slow path can trigger when it shouldn't. To guard
+ // against this, return here if the CC collector isn't running.
+ return from_ref;
+ }
+ DCHECK(region_space_ != nullptr) << "Read barrier slow path taken when CC isn't running?";
space::RegionSpace::RegionType rtype = region_space_->GetRegionType(from_ref);
if (rtype == space::RegionSpace::RegionType::kRegionTypeToSpace) {
// It's already marked.
diff --git a/runtime/gc/collector/semi_space-inl.h b/runtime/gc/collector/semi_space-inl.h
index 922a71c..7b19dc9 100644
--- a/runtime/gc/collector/semi_space-inl.h
+++ b/runtime/gc/collector/semi_space-inl.h
@@ -60,10 +60,6 @@ inline void SemiSpace::MarkObject(
if (obj == nullptr) {
return;
}
- if (kUseBakerOrBrooksReadBarrier) {
- // Verify all the objects have the correct forward pointer installed.
- obj->AssertReadBarrierPointer();
- }
if (from_space_->HasAddress(obj)) {
mirror::Object* forward_address = GetForwardingAddressInFromSpace(obj);
// If the object has already been moved, return the new forward address.
diff --git a/runtime/gc/reference_queue.cc b/runtime/gc/reference_queue.cc
index 4c93a4c..4ba3983 100644
--- a/runtime/gc/reference_queue.cc
+++ b/runtime/gc/reference_queue.cc
@@ -96,11 +96,11 @@ mirror::Reference* ReferenceQueue::DequeuePendingReference() {
<< "ref=" << ref << " rb_ptr=" << ref->GetReadBarrierPointer();
if (heap->ConcurrentCopyingCollector()->RegionSpace()->IsInToSpace(ref)) {
// Moving objects.
- ref->SetReadBarrierPointer(ReadBarrier::WhitePtr());
+ ref->AtomicSetReadBarrierPointer(ReadBarrier::GrayPtr(), ReadBarrier::WhitePtr());
CHECK_EQ(ref->GetReadBarrierPointer(), ReadBarrier::WhitePtr());
} else {
// Non-moving objects.
- ref->SetReadBarrierPointer(ReadBarrier::BlackPtr());
+ ref->AtomicSetReadBarrierPointer(ReadBarrier::GrayPtr(), ReadBarrier::BlackPtr());
CHECK_EQ(ref->GetReadBarrierPointer(), ReadBarrier::BlackPtr());
}
}