summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andreas Gampe <agampe@google.com> 2016-11-07 10:10:21 -0800
committer Andreas Gampe <agampe@google.com> 2016-11-07 10:10:59 -0800
commitdef4ee67bbff3b2a7280b93cca383c645984a710 (patch)
treefb2befdecb6a5ad31826e5c3de29c21cad8907ff
parentd98b4ed7a73af40f5292337495333616d9974da0 (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.h5
-rw-r--r--runtime/openjdkjvmti/object_tagging.cc34
-rw-r--r--runtime/openjdkjvmti/object_tagging.h34
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_)