1 class MatInMonitor {
 2     private Object _cache;
 3     private boolean _odd;
 4 
 5     public void test() {
 6         Object x = new Object();
 7         synchronized (x) {
 8             _cache = x;
 9         }
10     }
11 
12     public void test2() {
13         Object x = new Object();
14         Object y = new Object();
15         synchronized (x) {
16         synchronized (y) {
17             _cache = x; // steal the monitor of x, which is not the top of stack.
18         }}
19     }
20 
21     public void test3() {
22         Object x = new Object();
23         synchronized (x) {
24             if (_odd) {
25                 _cache = x;
26             }
27         }
28     }
29     // c2 doesn't support this nesting form. GeneratePairingInfo regards it as 'unbalanced'.
30     public void testNested() {
31         Object x = new Object();
32         synchronized (x) {
33         synchronized (x) {
34         synchronized (x) {
35             _cache = x;
36         }}}
37     }
38 
39     synchronized void bar() {
40         if (_odd) {
41             _cache = this; // escaping
42         }
43     }
44 
45     synchronized void foo() { bar(); }
46 
47     // Perfectly fine in C2. it is also a nesting lock after inlining.
48     // it passes GeneratePairingInfo becasue it is intra-procedural.
49     public void testNested2() {
50         synchronized(this) {
51             foo();
52         }
53     }
54 
55     public static void main(String[] args)  {
56         MatInMonitor kase = new MatInMonitor();
57 
58         for (int i = 0; i < 10_000; ++i) {
59             kase._odd = 0 == (i& 0xf);
60             kase.test();
61             kase.test2();
62             kase.test3();
63 
64             kase.testNested();
65             kase.testNested2();
66         }
67     }
68 }