diff options
author | 2016-11-07 10:10:21 -0800 | |
---|---|---|
committer | 2016-11-07 10:10:59 -0800 | |
commit | def4ee67bbff3b2a7280b93cca383c645984a710 (patch) | |
tree | fb2befdecb6a5ad31826e5c3de29c21cad8907ff | |
parent | d98b4ed7a73af40f5292337495333616d9974da0 (diff) |
ART: Extend Object tag table to be explicitly lockable
Expose the lock for the system weak holder. Add functions to lock
and unlock the object tagging table, and add accessors that assume
the table is already locked.
Bug: 31385354
Test: m test-art-host
Change-Id: I5a4328b0d439d13e6ace7965e22f01bbf8130f20
-rw-r--r-- | runtime/gc/system_weak.h | 5 | ||||
-rw-r--r-- | runtime/openjdkjvmti/object_tagging.cc | 34 | ||||
-rw-r--r-- | runtime/openjdkjvmti/object_tagging.h | 34 |
3 files changed, 73 insertions, 0 deletions
diff --git a/runtime/gc/system_weak.h b/runtime/gc/system_weak.h index 3910a280cc..887059b57f 100644 --- a/runtime/gc/system_weak.h +++ b/runtime/gc/system_weak.h @@ -69,6 +69,11 @@ class SystemWeakHolder : public AbstractSystemWeakHolder { new_weak_condition_.Broadcast(Thread::Current()); } + // WARNING: For lock annotations only. + Mutex* GetAllowDisallowLock() const RETURN_CAPABILITY(allow_disallow_lock_) { + return nullptr; + } + protected: void Wait(Thread* self) REQUIRES_SHARED(allow_disallow_lock_) { // Wait for GC's sweeping to complete and allow new records diff --git a/runtime/openjdkjvmti/object_tagging.cc b/runtime/openjdkjvmti/object_tagging.cc index b359f36316..b983e79658 100644 --- a/runtime/openjdkjvmti/object_tagging.cc +++ b/runtime/openjdkjvmti/object_tagging.cc @@ -47,6 +47,16 @@ namespace openjdkjvmti { +void ObjectTagTable::Lock() { + allow_disallow_lock_.ExclusiveLock(art::Thread::Current()); +} +void ObjectTagTable::Unlock() { + allow_disallow_lock_.ExclusiveUnlock(art::Thread::Current()); +} +void ObjectTagTable::AssertLocked() { + allow_disallow_lock_.AssertHeld(art::Thread::Current()); +} + void ObjectTagTable::UpdateTableWithReadBarrier() { update_since_last_sweep_ = true; @@ -80,6 +90,13 @@ bool ObjectTagTable::Remove(art::mirror::Object* obj, jlong* tag) { return RemoveLocked(self, obj, tag); } +bool ObjectTagTable::RemoveLocked(art::mirror::Object* obj, jlong* tag) { + art::Thread* self = art::Thread::Current(); + allow_disallow_lock_.AssertHeld(self); + Wait(self); + + return RemoveLocked(self, obj, tag); +} bool ObjectTagTable::RemoveLocked(art::Thread* self, art::mirror::Object* obj, jlong* tag) { auto it = tagged_objects_.find(art::GcRoot<art::mirror::Object>(obj)); @@ -109,12 +126,29 @@ bool ObjectTagTable::RemoveLocked(art::Thread* self, art::mirror::Object* obj, j } bool ObjectTagTable::Set(art::mirror::Object* obj, jlong new_tag) { + if (new_tag == 0) { + jlong tmp; + return Remove(obj, &tmp); + } + art::Thread* self = art::Thread::Current(); art::MutexLock mu(self, allow_disallow_lock_); Wait(self); return SetLocked(self, obj, new_tag); } +bool ObjectTagTable::SetLocked(art::mirror::Object* obj, jlong new_tag) { + if (new_tag == 0) { + jlong tmp; + return RemoveLocked(obj, &tmp); + } + + art::Thread* self = art::Thread::Current(); + allow_disallow_lock_.AssertHeld(self); + Wait(self); + + return SetLocked(self, obj, new_tag); +} bool ObjectTagTable::SetLocked(art::Thread* self, art::mirror::Object* obj, jlong new_tag) { auto it = tagged_objects_.find(art::GcRoot<art::mirror::Object>(obj)); diff --git a/runtime/openjdkjvmti/object_tagging.h b/runtime/openjdkjvmti/object_tagging.h index 071d139f18..997cedb093 100644 --- a/runtime/openjdkjvmti/object_tagging.h +++ b/runtime/openjdkjvmti/object_tagging.h @@ -46,10 +46,16 @@ class ObjectTagTable : public art::gc::SystemWeakHolder { bool Remove(art::mirror::Object* obj, jlong* tag) REQUIRES_SHARED(art::Locks::mutator_lock_) REQUIRES(!allow_disallow_lock_); + bool RemoveLocked(art::mirror::Object* obj, jlong* tag) + REQUIRES_SHARED(art::Locks::mutator_lock_) + REQUIRES(allow_disallow_lock_); bool Set(art::mirror::Object* obj, jlong tag) REQUIRES_SHARED(art::Locks::mutator_lock_) REQUIRES(!allow_disallow_lock_); + bool SetLocked(art::mirror::Object* obj, jlong tag) + REQUIRES_SHARED(art::Locks::mutator_lock_) + REQUIRES(allow_disallow_lock_); bool GetTag(art::mirror::Object* obj, jlong* result) REQUIRES_SHARED(art::Locks::mutator_lock_) @@ -60,6 +66,30 @@ class ObjectTagTable : public art::gc::SystemWeakHolder { return GetTagLocked(self, obj, result); } + bool GetTagLocked(art::mirror::Object* obj, jlong* result) + REQUIRES_SHARED(art::Locks::mutator_lock_) + REQUIRES(allow_disallow_lock_) { + art::Thread* self = art::Thread::Current(); + allow_disallow_lock_.AssertHeld(self); + Wait(self); + + return GetTagLocked(self, obj, result); + } + + jlong GetTagOrZero(art::mirror::Object* obj) + REQUIRES_SHARED(art::Locks::mutator_lock_) + REQUIRES(!allow_disallow_lock_) { + jlong tmp = 0; + GetTag(obj, &tmp); + return tmp; + } + jlong GetTagOrZeroLocked(art::mirror::Object* obj) + REQUIRES_SHARED(art::Locks::mutator_lock_) + REQUIRES(allow_disallow_lock_) { + jlong tmp = 0; + GetTagLocked(obj, &tmp); + return tmp; + } void Sweep(art::IsMarkedVisitor* visitor) REQUIRES_SHARED(art::Locks::mutator_lock_) @@ -74,6 +104,10 @@ class ObjectTagTable : public art::gc::SystemWeakHolder { REQUIRES_SHARED(art::Locks::mutator_lock_) REQUIRES(!allow_disallow_lock_); + void Lock() ACQUIRE(allow_disallow_lock_); + void Unlock() RELEASE(allow_disallow_lock_); + void AssertLocked() ASSERT_CAPABILITY(allow_disallow_lock_); + private: bool SetLocked(art::Thread* self, art::mirror::Object* obj, jlong tag) REQUIRES_SHARED(art::Locks::mutator_lock_) |