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 dalvik.annotation.optimization.DeadReferenceSafe;
18 import java.util.concurrent.atomic.AtomicInteger;
19 
20 @DeadReferenceSafe
21 public final class DeadReferenceSafeTest {
22   static AtomicInteger nFinalized = new AtomicInteger(0);
23   private static final int INNER_ITERS = 10;
24   static int count;
25   static boolean interpreted;
26   int n = 1;
27 
$noinline$loop()28   private static void $noinline$loop() {
29     DeadReferenceSafeTest x;
30     // The loop allocates INNER_ITERS DeadReferenceSafeTest objects.
31     for (int i = 0; i < INNER_ITERS; ++i) {
32       // We've allocated i objects so far.
33       x = new DeadReferenceSafeTest();
34       count += x.n;
35       // x is dead here.
36       if (i == 5) {
37         // With dead reference elimination, all 6 objects should have been finalized here.
38         // However the interpreter doesn't (yet?) play by the proper rules.
39         Main.$noinline$gcAndCheck(nFinalized, (interpreted ? 5 : 6), "DeadReferenceSafe",
40             "Failed to reclaim dead reference in @DeadReferenceSafe code!");
41       }
42     }
43   }
44 
reset(int expected_count)45   private static void reset(int expected_count) {
46     Runtime.getRuntime().gc();
47     System.runFinalization();
48     if (nFinalized.get() != expected_count) {
49       System.out.println("DeadReferenceSafeTest: Wrong number of finalized objects:"
50                          + nFinalized.get());
51     }
52     nFinalized.set(0);
53   }
54 
finalize()55   protected void finalize() {
56     nFinalized.incrementAndGet();
57   }
58 
runTest()59   public static void runTest() {
60     try {
61       interpreted = !Main.ensureCompiled(DeadReferenceSafeTest.class, "$noinline$loop");
62     } catch (NoSuchMethodException e) {
63       System.out.println("Unexpectedly threw " + e);
64     }
65 
66     $noinline$loop();
67 
68     if (count != INNER_ITERS) {
69       System.out.println("DeadReferenceSafeTest: Final count wrong: " + count);
70     }
71     reset(INNER_ITERS);
72   }
73 }
74