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 // DeadReferenceSafeTest, but with a ReachabilitySensitive annotation.
18 
19 import dalvik.annotation.optimization.DeadReferenceSafe;
20 import dalvik.annotation.optimization.ReachabilitySensitive;
21 import java.util.concurrent.atomic.AtomicInteger;
22 
23 @DeadReferenceSafe
24 public final class ReachabilitySensitiveTest {
25   static AtomicInteger nFinalized = new AtomicInteger(0);
26   private static final int INNER_ITERS = 10;
27   static int count;
28   @ReachabilitySensitive
29   int n = 1;
30 
$noinline$loop()31   private static void $noinline$loop() {
32     ReachabilitySensitiveTest x;
33     // The loop allocates INNER_ITERS ReachabilitySensitiveTest objects.
34     for (int i = 0; i < INNER_ITERS; ++i) {
35       // We've allocated i objects so far.
36       x = new ReachabilitySensitiveTest();
37       // ReachabilitySensitive reference.
38       count += x.n;
39       // x is dead here.
40       if (i == 5) {
41         // Since there is a ReachabilitySensitive reference to x.n, x should be kept live
42         // until it is reassigned. Thus the last instance should not be finalized.
43         Main.$noinline$gcAndCheck(nFinalized, 5, "ReachabilitySensitive",
44             "@ReachabilitySensitive failed to keep object live.");
45       }
46     }
47   }
48 
reset(int expected_count)49   private static void reset(int expected_count) {
50     Runtime.getRuntime().gc();
51     System.runFinalization();
52     if (nFinalized.get() != expected_count) {
53       System.out.println("ReachabilitySensitiveTest: Wrong number of finalized objects:"
54                          + nFinalized.get());
55     }
56     nFinalized.set(0);
57   }
58 
finalize()59   protected void finalize() {
60     nFinalized.incrementAndGet();
61   }
62 
runTest()63   public static void runTest() {
64     try {
65       Main.ensureCompiled(ReachabilitySensitiveTest.class, "$noinline$loop");
66     } catch (NoSuchMethodException e) {
67       System.out.println("Unexpectedly threw " + e);
68     }
69 
70     $noinline$loop();
71 
72     if (count != INNER_ITERS) {
73       System.out.println("ReachabilitySensitiveTest: Final count wrong: " + count);
74     }
75     reset(INNER_ITERS);
76   }
77 }
78