From 4cba0d979a11f955e6ec3c0f1bf61478af7aa810 Mon Sep 17 00:00:00 2001 From: Hiroshi Yamauchi Date: Wed, 21 May 2014 21:10:23 -0700 Subject: Add a read barrier for weak roots in monitors. A weak root requires a read barrier for the to-space invariant to hold because the object pointed to by a weak root can't be marked/forwarded like the one pointed to by a strong root (GC does not know if it's alive or not at that point) and because, without a read barrier, a mutator could access it and obtain a from-space reference, which would violate the to-space invariant. TODO: do similar for the other types of weak roots. Bug: 12687968 Change-Id: I563a0fa4f875e0c21ac96f57696959454e13b15a --- runtime/monitor.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'runtime/monitor.cc') diff --git a/runtime/monitor.cc b/runtime/monitor.cc index 0beb651..e0cd193 100644 --- a/runtime/monitor.cc +++ b/runtime/monitor.cc @@ -111,7 +111,7 @@ bool Monitor::Install(Thread* self) { MutexLock mu(self, monitor_lock_); // Uncontended mutex acquisition as monitor isn't yet public. CHECK(owner_ == nullptr || owner_ == self || owner_->IsSuspended()); // Propagate the lock state. - LockWord lw(obj_->GetLockWord(false)); + LockWord lw(GetObject()->GetLockWord(false)); switch (lw.GetState()) { case LockWord::kThinLocked: { CHECK_EQ(owner_->GetThreadId(), lw.ThinLockOwner()); @@ -137,7 +137,7 @@ bool Monitor::Install(Thread* self) { } LockWord fat(this); // Publish the updated lock word, which may race with other threads. - bool success = obj_->CasLockWord(lw, fat); + bool success = GetObject()->CasLockWord(lw, fat); // Lock profiling. if (success && owner_ != nullptr && lock_profiling_threshold_ != 0) { locking_method_ = owner_->GetCurrentMethod(&locking_dex_pc_); @@ -228,7 +228,7 @@ void Monitor::Lock(Thread* self) { monitor_lock_.Unlock(self); // Let go of locks in order. { ScopedThreadStateChange tsc(self, kBlocked); // Change to blocked and give up mutator_lock_. - self->SetMonitorEnterObject(obj_); + self->SetMonitorEnterObject(GetObject()); MutexLock mu2(self, monitor_lock_); // Reacquire monitor_lock_ without mutator_lock_ for Wait. if (owner_ != NULL) { // Did the owner_ give the lock up? monitor_contenders_.Wait(self); // Still contended so wait. @@ -363,7 +363,7 @@ bool Monitor::Unlock(Thread* self) { // We don't own this, so we're not allowed to unlock it. // The JNI spec says that we should throw IllegalMonitorStateException // in this case. - FailedUnlock(obj_, self, owner, this); + FailedUnlock(GetObject(), self, owner, this); return false; } return true; @@ -895,7 +895,7 @@ void Monitor::DescribeWait(std::ostream& os, const Thread* thread) { MutexLock mu(self, *thread->GetWaitMutex()); Monitor* monitor = thread->GetWaitMonitor(); if (monitor != nullptr) { - pretty_object = monitor->obj_; + pretty_object = monitor->GetObject(); } } else if (state == kBlocked) { wait_message = " - waiting to lock "; @@ -1101,12 +1101,13 @@ void MonitorList::SweepMonitorList(IsMarkedCallback* callback, void* arg) { MutexLock mu(Thread::Current(), monitor_list_lock_); for (auto it = list_.begin(); it != list_.end(); ) { Monitor* m = *it; - mirror::Object* obj = m->GetObject(); + // Disable the read barrier in GetObject() as this is called by GC. + mirror::Object* obj = m->GetObject(); // The object of a monitor can be null if we have deflated it. mirror::Object* new_obj = obj != nullptr ? callback(obj, arg) : nullptr; if (new_obj == nullptr) { VLOG(monitor) << "freeing monitor " << m << " belonging to unmarked object " - << m->GetObject(); + << obj; delete m; it = list_.erase(it); } else { -- cgit v1.1