| Alex Light | 270db1c | 2019-12-03 12:20:01 +0000 | [diff] [blame] | 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; |
| 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 | |
| 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 | } |
| 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 | } |
| 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 | } |
| 84 | public static void CheckEQ(Object a, int b) { |
| 85 | CheckEQ(((Integer)a).intValue(), b); |
| 86 | } |
| 87 | public static void CheckLE(Object a, Object b) { |
| 88 | CheckLE(((Integer)a).intValue(), ((Integer)b).intValue()); |
| 89 | } |
| 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 | } |
| 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 | } |