OSDN Git Service

ART: (Partially) fix lock aliasing
authorAndreas Gampe <agampe@google.com>
Tue, 18 Aug 2015 15:57:44 +0000 (08:57 -0700)
committerAndreas Gampe <agampe@google.com>
Wed, 19 Aug 2015 16:24:47 +0000 (09:24 -0700)
On monitor-exit, we must unlock all the registers which purport to
be locked at the current lock depth. These are lock aliases.

Bug: 20102779
Bug: 21169615
Bug: 21988678
Bug: 23300986
Change-Id: I6604871fc778d8f0ca9a99f6aad16a99ab62c599

runtime/verifier/register_line.h
test/800-smali/expected.txt
test/800-smali/smali/b_23300986.smali [new file with mode: 0644]
test/800-smali/src/Main.java

index f61e51f..a9c4c95 100644 (file)
@@ -344,6 +344,14 @@ class RegisterLine {
     } else {
       reg_to_lock_depths_.erase(it);
     }
+    // Need to unlock every register at the same lock depth. These are aliased locks.
+    uint32_t mask = 1 << depth;
+    for (auto& pair : reg_to_lock_depths_) {
+      if ((pair.second & mask) != 0) {
+        VLOG(verifier) << "Also unlocking " << pair.first;
+        pair.second ^= mask;
+      }
+    }
   }
 
   void ClearAllRegToLockDepths(size_t reg) {
index dd37cdb..21a8171 100644 (file)
@@ -41,4 +41,5 @@ b/22881413
 b/20843113
 b/23201502 (float)
 b/23201502 (double)
+b/23300986
 Done!
diff --git a/test/800-smali/smali/b_23300986.smali b/test/800-smali/smali/b_23300986.smali
new file mode 100644 (file)
index 0000000..5ed8e5e
--- /dev/null
@@ -0,0 +1,13 @@
+.class public LB23300986;
+
+.super Ljava/lang/Object;
+
+.method public static runAliasAfterEnter(Ljava/lang/Object;)V
+   .registers 3
+   monitor-enter v2        # Lock on parameter
+   move-object v1, v2      # Copy parameter into v1, establishing an alias.
+   monitor-exit v1         # Unlock on alias
+   monitor-enter v2        # Do it again.
+   monitor-exit v1
+   return-void
+.end method
index b481a1d..a89b849 100644 (file)
@@ -127,6 +127,8 @@ public class Main {
                 new NullPointerException(), null));
         testCases.add(new TestCase("b/23201502 (double)", "B23201502", "runDouble", null,
                 new NullPointerException(), null));
+        testCases.add(new TestCase("b/23300986", "B23300986", "runAliasAfterEnter",
+                new Object[] { new Object() }, null, null));
     }
 
     public void runTests() {