1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 import java.util.concurrent.atomic.AtomicInteger;
18 
19 public final class DeadReferenceUnsafeTest {
20   static AtomicInteger nFinalized = new AtomicInteger(0);
21   private static final int INNER_ITERS = 10;
22   static int count;
23   int n = 1;
24 
$noinline$loop()25   private static void $noinline$loop() {
26     DeadReferenceUnsafeTest x;
27     // The loop allocates INNER_ITERS DeadReferenceUnsafeTest objects.
28     for (int i = 0; i < INNER_ITERS; ++i) {
29       // We've allocated i objects so far.
30       x = new DeadReferenceUnsafeTest();
31       count += x.n;
32       // x is dead here.
33       if (i == 5) {
34         // Without dead reference elimination, the last object should be kept around,
35         // and only 5 objects should be relcaimed here.
36         Main.$noinline$gcAndCheck(nFinalized, 5, "DeadReferenceUnsafe",
37             "Failed to keep dead reference live in unannotated code!");
38       }
39     }
40   }
41 
reset(int expected_count)42   private static void reset(int expected_count) {
43     Runtime.getRuntime().gc();
44     System.runFinalization();
45     if (nFinalized.get() != expected_count) {
46       System.out.println("DeadReferenceUnsafeTest: Wrong number of finalized objects:"
47                          + nFinalized.get());
48     }
49     nFinalized.set(0);
50   }
51 
finalize()52   protected void finalize() {
53     nFinalized.incrementAndGet();
54   }
55 
runTest()56   public static void runTest() {
57     try {
58       Main.ensureCompiled(DeadReferenceUnsafeTest.class, "$noinline$loop");
59     } catch (NoSuchMethodException e) {
60       System.out.println("Unexpectedly threw " + e);
61     }
62 
63     $noinline$loop();
64 
65     if (count != INNER_ITERS) {
66       System.out.println("DeadReferenceUnsafeTest: Final count wrong: " + count);
67     }
68     reset(INNER_ITERS);
69   }
70 }
71