Home | History | Annotate | Download | only in src
      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 
     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 
     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 
     55   protected void finalize() {
     56     nFinalized.incrementAndGet();
     57   }
     58 
     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