/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import dalvik.annotation.optimization.DeadReferenceSafe; import java.util.concurrent.atomic.AtomicInteger; @DeadReferenceSafe public final class DeadReferenceSafeTest { static AtomicInteger nFinalized = new AtomicInteger(0); private static final int INNER_ITERS = 10; static int count; static boolean interpreted; int n = 1; private static void $noinline$loop() { DeadReferenceSafeTest x; // The loop allocates INNER_ITERS DeadReferenceSafeTest objects. for (int i = 0; i < INNER_ITERS; ++i) { // We've allocated i objects so far. x = new DeadReferenceSafeTest(); count += x.n; // x is dead here. if (i == 5) { // With dead reference elimination, all 6 objects should have been finalized here. // However the interpreter doesn't (yet?) play by the proper rules. Main.$noinline$gcAndCheck(nFinalized, (interpreted ? 5 : 6), "DeadReferenceSafe", "Failed to reclaim dead reference in @DeadReferenceSafe code!"); } } } private static void reset(int expected_count) { Runtime.getRuntime().gc(); System.runFinalization(); if (nFinalized.get() != expected_count) { System.out.println("DeadReferenceSafeTest: Wrong number of finalized objects:" + nFinalized.get()); } nFinalized.set(0); } protected void finalize() { nFinalized.incrementAndGet(); } public static void runTest() { try { interpreted = !Main.ensureCompiled(DeadReferenceSafeTest.class, "$noinline$loop"); } catch (NoSuchMethodException e) { System.out.println("Unexpectedly threw " + e); } $noinline$loop(); if (count != INNER_ITERS) { System.out.println("DeadReferenceSafeTest: Final count wrong: " + count); } reset(INNER_ITERS); } }