1 /*
2  * Copyright (C) 2016 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 import java.util.IdentityHashMap;
17 import dalvik.system.VMRuntime;
18 
19 public class Main {
main(String[] args)20   public static void main(String[] args) {
21     System.loadLibrary(args[0]);
22     int initialSize = monitorListSize();
23     IdentityHashMap<Object, Integer> all = new IdentityHashMap();
24     for (int i = 0; i < 5000; ++i) {
25       Object obj = new Object();
26       synchronized(obj) {
27         // Should force inflation.
28         all.put(obj, obj.hashCode());
29       }
30     }
31     // Since monitor deflation is delayed significantly, we believe that even with an intervening
32     // GC, monitors should remain inflated.  We allow some slop for unrelated concurrent runtime
33     // actions.
34     int inflatedSize = monitorListSize();
35     if (inflatedSize >= initialSize + 4000) {
36         System.out.println("Monitor list grew by at least 4000 monitors");
37     } else {
38         System.out.println("Monitor list did not grow as expected");
39     }
40     // Encourage monitor deflation.
41     // trim() (Heap::Trim()) deflates only in JANK_IMPERCEPTIBLE state.
42     // Some of this mirrors code in ActivityThread.java.
43     final int DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE = 0;
44     final int DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE = 1;
45     VMRuntime.getRuntime().updateProcessState(DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE);
46     System.gc();
47     System.runFinalization();
48     trim();
49     VMRuntime.getRuntime().updateProcessState(DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE);
50     int finalSize = monitorListSize();
51     if (finalSize > initialSize + 1000) {
52         System.out.println("Monitor list failed to shrink properly");
53     } else {
54         System.out.println("Monitor list shrank correctly");
55     }
56     int j = 0;
57     for (Object obj: all.keySet()) {
58       ++j;
59       if (obj.hashCode() != all.get(obj)) {
60         throw new AssertionError("Failed hashcode test!");
61       }
62     }
63     System.out.println("Finished first check");
64     for (Object obj: all.keySet()) {
65       ++j;
66       synchronized(obj) {
67         if (obj.hashCode() != all.get(obj)) {
68           throw new AssertionError("Failed hashcode test!");
69         }
70       }
71     }
72     System.out.println("Finished second check");
73     System.out.println("Total checks: " + j);
74   }
75 
trim()76   private static native void trim();
77 
monitorListSize()78   private static native int monitorListSize();
79 }
80