OSDN Git Service

ART: Extend Object tag table to be explicitly lockable
authorAndreas Gampe <agampe@google.com>
Mon, 7 Nov 2016 18:10:21 +0000 (10:10 -0800)
committerAndreas Gampe <agampe@google.com>
Mon, 7 Nov 2016 18:10:59 +0000 (10:10 -0800)
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

runtime/gc/system_weak.h
runtime/openjdkjvmti/object_tagging.cc
runtime/openjdkjvmti/object_tagging.h

index 3910a28..887059b 100644 (file)
@@ -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
index b359f36..b983e79 100644 (file)
 
 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));
index 071d139..997cedb 100644 (file)
@@ -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_)