| /* |
| * Copyright (C) 2016 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. |
| */ |
| |
| package art; |
| |
| import java.lang.ref.WeakReference; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| |
| public class Test903 { |
| public static void run() { |
| Main.bindAgentJNIForClass(Test903.class); |
| |
| doTest(); |
| testGetTaggedObjects(); |
| testTags(); |
| } |
| |
| public static void doTest() { |
| WeakReference<Object> weak = test(); |
| |
| Runtime.getRuntime().gc(); |
| Runtime.getRuntime().gc(); |
| |
| if (weak.get() != null) { |
| throw new RuntimeException("WeakReference not cleared"); |
| } |
| } |
| |
| public static void testTags() { |
| Object o = new Object(); |
| long[] res = testTagsInDifferentEnvs(o, 100, 10); |
| System.out.println(Arrays.toString(res)); |
| } |
| |
| private static WeakReference<Object> test() { |
| Object o1 = new Object(); |
| Main.setTag(o1, 1); |
| |
| Object o2 = new Object(); |
| Main.setTag(o2, 2); |
| |
| checkTag(o1, 1); |
| checkTag(o2, 2); |
| |
| Runtime.getRuntime().gc(); |
| Runtime.getRuntime().gc(); |
| |
| checkTag(o1, 1); |
| checkTag(o2, 2); |
| |
| Runtime.getRuntime().gc(); |
| Runtime.getRuntime().gc(); |
| |
| Main.setTag(o1, 10); |
| Main.setTag(o2, 20); |
| |
| checkTag(o1, 10); |
| checkTag(o2, 20); |
| |
| return new WeakReference<Object>(o1); |
| } |
| |
| private static void checkTag(Object o, long expectedTag) { |
| long tag = Main.getTag(o); |
| if (expectedTag != tag) { |
| throw new RuntimeException("Unexpected tag " + tag + ", expected " + expectedTag); |
| } |
| } |
| |
| private static void testGetTaggedObjects() { |
| // Use an array list to ensure that the objects stay live for a bit. Also gives us a source |
| // to compare to. We use index % 10 as the tag. |
| ArrayList<Object> l = new ArrayList<>(); |
| |
| for (int i = 0; i < 20; i++) { |
| Integer o = new Integer(i); |
| l.add(o); |
| if (i % 10 != 0) { |
| Main.setTag(o, i % 10); |
| } |
| } |
| |
| testGetTaggedObjectsRun(l, null, false, false); |
| testGetTaggedObjectsRun(l, null, true, true); |
| testGetTaggedObjectsRun(l, new long[] { 2, 5 }, true, true); |
| testGetTaggedObjectsRun(l, null, false, true); |
| testGetTaggedObjectsRun(l, null, true, false); |
| } |
| |
| private static void testGetTaggedObjectsRun(ArrayList<Object> l, long[] searchTags, |
| boolean returnObjects, boolean returnTags) { |
| Object[] result = getTaggedObjects(searchTags, returnObjects, returnTags); |
| |
| Object[] objects = (Object[])result[0]; |
| long[] tags = (long[])result[1]; |
| int count = (int)result[2]; |
| |
| System.out.println(count); |
| printArraysSorted(objects, tags); |
| } |
| |
| private static void printArraysSorted(Object[] objects, long[] tags) { |
| if (objects == null && tags == null) { |
| System.out.println("<nothing>"); |
| return; |
| } |
| |
| int l1 = objects == null ? 0 : objects.length; |
| int l2 = tags == null ? 0 : tags.length; |
| int l = Math.max(l1, l2); |
| Pair[] tmp = new Pair[l]; |
| for (int i = 0; i < l; i++) { |
| tmp[i] = new Pair(objects == null ? null : objects[i], tags == null ? 0 : tags[i]); |
| } |
| |
| Arrays.sort(tmp); |
| |
| System.out.println(Arrays.toString(tmp)); |
| } |
| |
| private static class Pair implements Comparable<Pair> { |
| Object obj; |
| long tag; |
| public Pair(Object o, long t) { |
| obj = o; |
| tag = t; |
| } |
| |
| public int compareTo(Pair p) { |
| if (tag != p.tag) { |
| return Long.compare(tag, p.tag); |
| } |
| |
| if ((obj instanceof Comparable) && (p.obj instanceof Comparable)) { |
| // It's not really correct, but w/e, best effort. |
| int result = ((Comparable<Object>)obj).compareTo(p.obj); |
| if (result != 0) { |
| return result; |
| } |
| } |
| |
| if (obj != null && p.obj != null) { |
| return obj.hashCode() - p.obj.hashCode(); |
| } |
| |
| if (obj != null) { |
| return 1; |
| } |
| |
| if (p.obj != null) { |
| return -1; |
| } |
| |
| return hashCode() - p.hashCode(); |
| } |
| |
| public String toString() { |
| return "<" + obj + ";" + tag + ">"; |
| } |
| } |
| |
| private static native Object[] getTaggedObjects(long[] searchTags, boolean returnObjects, |
| boolean returnTags); |
| private static native long[] testTagsInDifferentEnvs(Object o, long baseTag, int n); |
| } |