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 
17 package art;
18 
19 import java.lang.ref.WeakReference;
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 
23 public class Test903 {
run()24   public static void run() {
25     doTest();
26     testGetTaggedObjects();
27     testTags();
28   }
29 
doTest()30   public static void doTest() {
31     WeakReference<Object> weak = test();
32 
33     Runtime.getRuntime().gc();
34     Runtime.getRuntime().gc();
35 
36     if (weak.get() != null) {
37       throw new RuntimeException("WeakReference not cleared");
38     }
39   }
40 
testTags()41   public static void testTags() {
42     Object o = new Object();
43     long[] res = testTagsInDifferentEnvs(o, 100, 10);
44     System.out.println(Arrays.toString(res));
45   }
46 
test()47   private static WeakReference<Object> test() {
48     Object o1 = new Object();
49     Main.setTag(o1, 1);
50 
51     Object o2 = new Object();
52     Main.setTag(o2, 2);
53 
54     checkTag(o1, 1);
55     checkTag(o2, 2);
56 
57     Runtime.getRuntime().gc();
58     Runtime.getRuntime().gc();
59 
60     checkTag(o1, 1);
61     checkTag(o2, 2);
62 
63     Runtime.getRuntime().gc();
64     Runtime.getRuntime().gc();
65 
66     Main.setTag(o1, 10);
67     Main.setTag(o2, 20);
68 
69     checkTag(o1, 10);
70     checkTag(o2, 20);
71 
72     return new WeakReference<Object>(o1);
73   }
74 
checkTag(Object o, long expectedTag)75   private static void checkTag(Object o, long expectedTag) {
76     long tag = Main.getTag(o);
77     if (expectedTag != tag) {
78       throw new RuntimeException("Unexpected tag " + tag + ", expected " + expectedTag);
79     }
80   }
81 
testGetTaggedObjects()82   private static void testGetTaggedObjects() {
83     // Use an array list to ensure that the objects stay live for a bit. Also gives us a source
84     // to compare to. We use index % 10 as the tag.
85     ArrayList<Object> l = new ArrayList<>();
86 
87     for (int i = 0; i < 20; i++) {
88       Integer o = new Integer(i);
89       l.add(o);
90       if (i % 10 != 0) {
91         Main.setTag(o, i % 10);
92       }
93     }
94 
95     testGetTaggedObjectsRun(l, null, false, false);
96     testGetTaggedObjectsRun(l, null, true, true);
97     testGetTaggedObjectsRun(l, new long[] { 2, 5 }, true, true);
98     testGetTaggedObjectsRun(l, null, false, true);
99     testGetTaggedObjectsRun(l, null, true, false);
100   }
101 
testGetTaggedObjectsRun(ArrayList<Object> l, long[] searchTags, boolean returnObjects, boolean returnTags)102   private static void testGetTaggedObjectsRun(ArrayList<Object> l, long[] searchTags,
103       boolean returnObjects, boolean returnTags) {
104     Object[] result = getTaggedObjects(searchTags, returnObjects, returnTags);
105 
106     Object[] objects = (Object[])result[0];
107     long[] tags = (long[])result[1];
108     int count = (int)result[2];
109 
110     System.out.println(count);
111     printArraysSorted(objects, tags);
112   }
113 
printArraysSorted(Object[] objects, long[] tags)114   private static void printArraysSorted(Object[] objects, long[] tags) {
115     if (objects == null && tags == null) {
116       System.out.println("<nothing>");
117       return;
118     }
119 
120     int l1 = objects == null ? 0 : objects.length;
121     int l2 = tags == null ? 0 : tags.length;
122     int l = Math.max(l1, l2);
123     Pair[] tmp = new Pair[l];
124     for (int i = 0; i < l; i++) {
125       tmp[i] = new Pair(objects == null ? null : objects[i], tags == null ? 0 : tags[i]);
126     }
127 
128     Arrays.sort(tmp);
129 
130     System.out.println(Arrays.toString(tmp));
131   }
132 
133   private static class Pair implements Comparable<Pair> {
134     Object obj;
135     long tag;
Pair(Object o, long t)136     public Pair(Object o, long t) {
137       obj = o;
138       tag = t;
139     }
140 
compareTo(Pair p)141     public int compareTo(Pair p) {
142       if (tag != p.tag) {
143         return Long.compare(tag, p.tag);
144       }
145 
146       if ((obj instanceof Comparable) && (p.obj instanceof Comparable)) {
147         // It's not really correct, but w/e, best effort.
148         int result = ((Comparable<Object>)obj).compareTo(p.obj);
149         if (result != 0) {
150           return result;
151         }
152       }
153 
154       if (obj != null && p.obj != null) {
155         return obj.hashCode() - p.obj.hashCode();
156       }
157 
158       if (obj != null) {
159         return 1;
160       }
161 
162       if (p.obj != null) {
163         return -1;
164       }
165 
166       return hashCode() - p.hashCode();
167     }
168 
toString()169     public String toString() {
170       return "<" + obj + ";" + tag + ">";
171     }
172   }
173 
getTaggedObjects(long[] searchTags, boolean returnObjects, boolean returnTags)174   private static native Object[] getTaggedObjects(long[] searchTags, boolean returnObjects,
175       boolean returnTags);
testTagsInDifferentEnvs(Object o, long baseTag, int n)176   private static native long[] testTagsInDifferentEnvs(Object o, long baseTag, int n);
177 }
178