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