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 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 
     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 
     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 
     52   protected void finalize() {
     53     nFinalized.incrementAndGet();
     54   }
     55 
     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