1 /* 2 * Copyright (C) 2017 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 art.*; 18 import java.util.*; 19 import java.lang.invoke.*; 20 import java.io.*; 21 import java.util.zip.*; 22 23 public class Main { 24 public static final String TEST_NAME = "2000-virtual-list-structural"; 25 public static final boolean PRINT_COUNT = false; 26 public static MethodHandles.Lookup lookup = MethodHandles.publicLookup(); 27 public static MethodHandle getcnt; 28 public static MethodHandle get_total_cnt; GetHandles()29 public static void GetHandles() throws Throwable { 30 getcnt = lookup.findGetter(AbstractCollection.class, "cnt", Integer.TYPE); 31 get_total_cnt = lookup.findStaticGetter(AbstractCollection.class, "TOTAL_COUNT", Integer.TYPE); 32 } 33 GetDexBytes()34 public static byte[] GetDexBytes() throws Throwable { 35 String jar_loc = System.getenv("DEX_LOCATION") + "/" + TEST_NAME + "-ex.jar"; 36 try (ZipFile zip = new ZipFile(new File(jar_loc))) { 37 ZipEntry entry = zip.getEntry("classes.dex"); 38 try (InputStream is = zip.getInputStream(entry)) { 39 byte[] res = new byte[(int)entry.getSize()]; 40 is.read(res); 41 return res; 42 } 43 } 44 } PrintListAndData(AbstractCollection<String> c)45 public static void PrintListAndData(AbstractCollection<String> c) throws Throwable { 46 if (PRINT_COUNT) { 47 System.out.println("List is: " + c + " count = " + getcnt.invoke(c) + " TOTAL_COUNT = " + get_total_cnt.invoke()); 48 } else { 49 System.out.println("List is: " + c); 50 } 51 } main(String[] args)52 public static void main(String[] args) throws Throwable { 53 AbstractCollection<String> l1 = (AbstractCollection<String>)Arrays.asList("a", "b", "c", "d"); 54 AbstractCollection<String> l2 = new ArrayList<>(); 55 l2.add("1"); 56 l2.add("2"); 57 l2.add("3"); 58 l2.add("4"); 59 Redefinition.doCommonStructuralClassRedefinition(AbstractCollection.class, GetDexBytes()); 60 GetHandles(); 61 AbstractCollection<String> l3 = new HashSet<>(l2); 62 AbstractCollection<String> l4 = new LinkedList<>(l1); 63 PrintListAndData(l1); 64 PrintListAndData(l2); 65 for (int i = 0; i < 1000; i++) { 66 l2.add("xyz: " + i); 67 } 68 PrintListAndData(l2); 69 PrintListAndData(l3); 70 PrintListAndData(l4); 71 CheckLE(getcnt.invoke(l1), get_total_cnt.invoke()); 72 CheckLE(getcnt.invoke(l2), get_total_cnt.invoke()); 73 CheckLE(getcnt.invoke(l3), get_total_cnt.invoke()); 74 CheckLE(getcnt.invoke(l4), get_total_cnt.invoke()); 75 CheckEQ(getcnt.invoke(l1), 0); 76 CheckLE(getcnt.invoke(l2), 0); 77 CheckLE(getcnt.invoke(l1), getcnt.invoke(l2)); 78 CheckLE(getcnt.invoke(l1), getcnt.invoke(l3)); 79 CheckLE(getcnt.invoke(l1), getcnt.invoke(l4)); 80 CheckLE(getcnt.invoke(l2), getcnt.invoke(l3)); 81 CheckLE(getcnt.invoke(l2), getcnt.invoke(l4)); 82 CheckLE(getcnt.invoke(l3), getcnt.invoke(l4)); 83 } CheckEQ(Object a, int b)84 public static void CheckEQ(Object a, int b) { 85 CheckEQ(((Integer)a).intValue(), b); 86 } CheckLE(Object a, Object b)87 public static void CheckLE(Object a, Object b) { 88 CheckLE(((Integer)a).intValue(), ((Integer)b).intValue()); 89 } CheckEQ(int a, int b)90 public static void CheckEQ(int a, int b) { 91 if (a != b) { 92 throw new Error(a + " is not equal to " + b); 93 } 94 } CheckLE(int a, int b)95 public static void CheckLE(int a, int b) { 96 if (!(a <= b)) { 97 throw new Error(a + " is not less than or equal to " + b); 98 } 99 } 100 } 101