18da6d03176651594b821cd3531894c372ca640d5Andreas Gampe/* 28da6d03176651594b821cd3531894c372ca640d5Andreas Gampe * Copyright (C) 2016 The Android Open Source Project 38da6d03176651594b821cd3531894c372ca640d5Andreas Gampe * 48da6d03176651594b821cd3531894c372ca640d5Andreas Gampe * Licensed under the Apache License, Version 2.0 (the "License"); 58da6d03176651594b821cd3531894c372ca640d5Andreas Gampe * you may not use this file except in compliance with the License. 68da6d03176651594b821cd3531894c372ca640d5Andreas Gampe * You may obtain a copy of the License at 78da6d03176651594b821cd3531894c372ca640d5Andreas Gampe * 88da6d03176651594b821cd3531894c372ca640d5Andreas Gampe * http://www.apache.org/licenses/LICENSE-2.0 98da6d03176651594b821cd3531894c372ca640d5Andreas Gampe * 108da6d03176651594b821cd3531894c372ca640d5Andreas Gampe * Unless required by applicable law or agreed to in writing, software 118da6d03176651594b821cd3531894c372ca640d5Andreas Gampe * distributed under the License is distributed on an "AS IS" BASIS, 128da6d03176651594b821cd3531894c372ca640d5Andreas Gampe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138da6d03176651594b821cd3531894c372ca640d5Andreas Gampe * See the License for the specific language governing permissions and 148da6d03176651594b821cd3531894c372ca640d5Andreas Gampe * limitations under the License. 158da6d03176651594b821cd3531894c372ca640d5Andreas Gampe */ 168da6d03176651594b821cd3531894c372ca640d5Andreas Gampe 174665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampepackage art; 184665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampe 19037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampeimport java.io.BufferedReader; 20037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampeimport java.io.File; 21037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampeimport java.io.FileReader; 228da6d03176651594b821cd3531894c372ca640d5Andreas Gampeimport java.util.ArrayList; 238a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampeimport java.util.Arrays; 2470bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampeimport java.util.Collections; 255d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampeimport java.util.HashMap; 265d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampeimport java.util.HashSet; 27e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampeimport java.util.concurrent.CountDownLatch; 288da6d03176651594b821cd3531894c372ca640d5Andreas Gampe 294665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampepublic class Test913 { 304665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampe public static void run() throws Exception { 318da6d03176651594b821cd3531894c372ca640d5Andreas Gampe doTest(); 32e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe 33e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe // Use a countdown latch for synchronization, as join() will introduce more roots. 34e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe final CountDownLatch cdl1 = new CountDownLatch(1); 35e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe 36e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe // Run the follow-references tests on a dedicated thread so we know the specific Thread type. 37e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe Thread t = new Thread() { 38e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe @Override 39e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe public void run() { 40e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe try { 41e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe Test913.runFollowReferences(); 42e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe } catch (Exception e) { 43e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe throw new RuntimeException(e); 44e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe } 45e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe cdl1.countDown(); 46e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe } 47e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe }; 48e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe t.start(); 49e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe cdl1.await(); 50037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe 51037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe doExtensionTests(); 52e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe } 53e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe 54e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe public static void runFollowReferences() throws Exception { 558a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe new TestConfig().doFollowReferencesTest(); 563ec8e40930c87be425a4e74d6a617b6396cfe003Andreas Gampe 575f942039b83ec9a54aaa0d6badec4d26a921027bAndreas Gampe Runtime.getRuntime().gc(); 585f942039b83ec9a54aaa0d6badec4d26a921027bAndreas Gampe Runtime.getRuntime().gc(); 595f942039b83ec9a54aaa0d6badec4d26a921027bAndreas Gampe 60c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe new TestConfig(null, 0, 1, -1).doFollowReferencesTest(); 61c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe 62c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe Runtime.getRuntime().gc(); 63c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe Runtime.getRuntime().gc(); 64c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe 65c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe new TestConfig(null, 0, Integer.MAX_VALUE, 1).doFollowReferencesTest(); 66c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe 67c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe Runtime.getRuntime().gc(); 68c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe Runtime.getRuntime().gc(); 69c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe 703ec8e40930c87be425a4e74d6a617b6396cfe003Andreas Gampe doStringTest(); 715f942039b83ec9a54aaa0d6badec4d26a921027bAndreas Gampe 725f942039b83ec9a54aaa0d6badec4d26a921027bAndreas Gampe Runtime.getRuntime().gc(); 735f942039b83ec9a54aaa0d6badec4d26a921027bAndreas Gampe Runtime.getRuntime().gc(); 745f942039b83ec9a54aaa0d6badec4d26a921027bAndreas Gampe 75becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe doPrimitiveArrayTest(); 76e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe doPrimitiveFieldTest(); 7738da9f2c12d5e094bebf9c0982a82aa7648c200aAndreas Gampe 785f942039b83ec9a54aaa0d6badec4d26a921027bAndreas Gampe Runtime.getRuntime().gc(); 795f942039b83ec9a54aaa0d6badec4d26a921027bAndreas Gampe Runtime.getRuntime().gc(); 805f942039b83ec9a54aaa0d6badec4d26a921027bAndreas Gampe 8138da9f2c12d5e094bebf9c0982a82aa7648c200aAndreas Gampe // Test klass filter. 8238da9f2c12d5e094bebf9c0982a82aa7648c200aAndreas Gampe System.out.println("--- klass ---"); 8338da9f2c12d5e094bebf9c0982a82aa7648c200aAndreas Gampe new TestConfig(A.class, 0).doFollowReferencesTest(); 846ea0607fcda940748580b0b68a2da8ea61da4719Andreas Gampe 856ea0607fcda940748580b0b68a2da8ea61da4719Andreas Gampe // Test heap filter. 866ea0607fcda940748580b0b68a2da8ea61da4719Andreas Gampe System.out.println("--- heap_filter ---"); 876ea0607fcda940748580b0b68a2da8ea61da4719Andreas Gampe System.out.println("---- tagged objects"); 886ea0607fcda940748580b0b68a2da8ea61da4719Andreas Gampe new TestConfig(null, 0x4).doFollowReferencesTest(); 896ea0607fcda940748580b0b68a2da8ea61da4719Andreas Gampe System.out.println("---- untagged objects"); 906ea0607fcda940748580b0b68a2da8ea61da4719Andreas Gampe new TestConfig(null, 0x8).doFollowReferencesTest(); 916ea0607fcda940748580b0b68a2da8ea61da4719Andreas Gampe System.out.println("---- tagged classes"); 926ea0607fcda940748580b0b68a2da8ea61da4719Andreas Gampe new TestConfig(null, 0x10).doFollowReferencesTest(); 936ea0607fcda940748580b0b68a2da8ea61da4719Andreas Gampe System.out.println("---- untagged classes"); 946ea0607fcda940748580b0b68a2da8ea61da4719Andreas Gampe new TestConfig(null, 0x20).doFollowReferencesTest(); 958da6d03176651594b821cd3531894c372ca640d5Andreas Gampe } 968da6d03176651594b821cd3531894c372ca640d5Andreas Gampe 978da6d03176651594b821cd3531894c372ca640d5Andreas Gampe public static void doTest() throws Exception { 988da6d03176651594b821cd3531894c372ca640d5Andreas Gampe setupGcCallback(); 998da6d03176651594b821cd3531894c372ca640d5Andreas Gampe 1008da6d03176651594b821cd3531894c372ca640d5Andreas Gampe enableGcTracking(true); 1014665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampe runGc(); 1028da6d03176651594b821cd3531894c372ca640d5Andreas Gampe enableGcTracking(false); 1038da6d03176651594b821cd3531894c372ca640d5Andreas Gampe } 1048da6d03176651594b821cd3531894c372ca640d5Andreas Gampe 1053ec8e40930c87be425a4e74d6a617b6396cfe003Andreas Gampe public static void doStringTest() throws Exception { 1065f942039b83ec9a54aaa0d6badec4d26a921027bAndreas Gampe final String str = new String("HelloWorld"); 1075f942039b83ec9a54aaa0d6badec4d26a921027bAndreas Gampe final String str2 = new String(""); 1083ec8e40930c87be425a4e74d6a617b6396cfe003Andreas Gampe Object o = new Object() { 1093ec8e40930c87be425a4e74d6a617b6396cfe003Andreas Gampe String s = str; 1105f942039b83ec9a54aaa0d6badec4d26a921027bAndreas Gampe String s2 = str2; 1113ec8e40930c87be425a4e74d6a617b6396cfe003Andreas Gampe }; 1123ec8e40930c87be425a4e74d6a617b6396cfe003Andreas Gampe 1133ec8e40930c87be425a4e74d6a617b6396cfe003Andreas Gampe setTag(str, 1); 1145f942039b83ec9a54aaa0d6badec4d26a921027bAndreas Gampe setTag(str2, 2); 1153ec8e40930c87be425a4e74d6a617b6396cfe003Andreas Gampe System.out.println(Arrays.toString(followReferencesString(o))); 1163ec8e40930c87be425a4e74d6a617b6396cfe003Andreas Gampe System.out.println(getTag(str)); 1175f942039b83ec9a54aaa0d6badec4d26a921027bAndreas Gampe System.out.println(getTag(str2)); 1183ec8e40930c87be425a4e74d6a617b6396cfe003Andreas Gampe } 1193ec8e40930c87be425a4e74d6a617b6396cfe003Andreas Gampe 120becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe public static void doPrimitiveArrayTest() throws Exception { 121becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe final boolean[] zArray = new boolean[] { false, true }; 122becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe setTag(zArray, 1); 123becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe 124becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe final byte[] bArray = new byte[] { 1, 2, 3 }; 125becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe setTag(bArray, 2); 126becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe 127becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe final char[] cArray = new char[] { 'A', 'Z' }; 128becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe setTag(cArray, 3); 129becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe 130becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe final short[] sArray = new short[] { 1, 2, 3 }; 131becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe setTag(sArray, 4); 132becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe 133becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe final int[] iArray = new int[] { 1, 2, 3 }; 134becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe setTag(iArray, 5); 135becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe 136becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe final float[] fArray = new float[] { 0.0f, 1.0f }; 137becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe setTag(fArray, 6); 138becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe 139becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe final long[] lArray = new long[] { 1, 2, 3 }; 140becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe setTag(lArray, 7); 141becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe 142becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe final double[] dArray = new double[] { 0.0, 1.0 }; 143becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe setTag(dArray, 8); 144becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe 145becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe Object o = new Object() { 146becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe Object z = zArray; 147becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe Object b = bArray; 148becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe Object c = cArray; 149becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe Object s = sArray; 150becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe Object i = iArray; 151becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe Object f = fArray; 152becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe Object l = lArray; 153becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe Object d = dArray; 154becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe }; 155becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe 156becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe System.out.println(followReferencesPrimitiveArray(o)); 157becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe System.out.print(getTag(zArray)); 158becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe System.out.print(getTag(bArray)); 159becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe System.out.print(getTag(cArray)); 160becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe System.out.print(getTag(sArray)); 161becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe System.out.print(getTag(iArray)); 162becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe System.out.print(getTag(fArray)); 163becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe System.out.print(getTag(lArray)); 164becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe System.out.println(getTag(dArray)); 165becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe } 166becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe 167e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe public static void doPrimitiveFieldTest() throws Exception { 168e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe // Force GCs to clean up dirt. 169e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe Runtime.getRuntime().gc(); 170e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe Runtime.getRuntime().gc(); 171e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 172e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe doTestPrimitiveFieldsClasses(); 173e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 174e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe doTestPrimitiveFieldsIntegral(); 175e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 176e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe // Force GCs to clean up dirt. 177e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe Runtime.getRuntime().gc(); 178e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe Runtime.getRuntime().gc(); 179e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 180e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe doTestPrimitiveFieldsFloat(); 181e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 182e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe // Force GCs to clean up dirt. 183e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe Runtime.getRuntime().gc(); 184e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe Runtime.getRuntime().gc(); 185e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe } 186e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 187e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe private static void doTestPrimitiveFieldsClasses() { 188e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe setTag(IntObject.class, 10000); 189e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe System.out.println(followReferencesPrimitiveFields(IntObject.class)); 190e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe System.out.println(getTag(IntObject.class)); 191e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe setTag(IntObject.class, 0); 192e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 193e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe setTag(FloatObject.class, 10000); 194e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe System.out.println(followReferencesPrimitiveFields(FloatObject.class)); 195e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe System.out.println(getTag(FloatObject.class)); 196e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe setTag(FloatObject.class, 0); 197e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 198e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe setTag(Inf1.class, 10000); 199e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe System.out.println(followReferencesPrimitiveFields(Inf1.class)); 200e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe System.out.println(getTag(Inf1.class)); 201e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe setTag(Inf1.class, 0); 202e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 203e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe setTag(Inf2.class, 10000); 204e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe System.out.println(followReferencesPrimitiveFields(Inf2.class)); 205e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe System.out.println(getTag(Inf2.class)); 206e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe setTag(Inf2.class, 0); 207e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe } 208e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 209e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe private static void doTestPrimitiveFieldsIntegral() { 210e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe IntObject intObject = new IntObject(); 211e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe setTag(intObject, 10000); 212e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe System.out.println(followReferencesPrimitiveFields(intObject)); 213e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe System.out.println(getTag(intObject)); 214e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe } 215e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 216e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe private static void doTestPrimitiveFieldsFloat() { 217e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe FloatObject floatObject = new FloatObject(); 218e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe setTag(floatObject, 10000); 219e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe System.out.println(followReferencesPrimitiveFields(floatObject)); 220e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe System.out.println(getTag(floatObject)); 221e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe } 222e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 223037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe static ArrayList<Object> extensionTestHolder; 224037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe 225037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe private static void doExtensionTests() { 226037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe checkForExtensionApis(); 227037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe 228037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe extensionTestHolder = new ArrayList<>(); 229037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe System.out.println(); 230037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe 231037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe try { 232037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe getHeapName(-1); 233037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe System.out.println("Expected failure for -1"); 234037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe } catch (Exception e) { 235037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe } 236037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe System.out.println(getHeapName(0)); 237037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe System.out.println(getHeapName(1)); 238037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe System.out.println(getHeapName(2)); 239037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe System.out.println(getHeapName(3)); 240037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe try { 241037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe getHeapName(4); 242037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe System.out.println("Expected failure for -1"); 243037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe } catch (Exception e) { 244037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe } 245037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe 246037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe System.out.println(); 247037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe 248037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe setTag(Object.class, 100000); 249037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe int objectClassHeapId = getObjectHeapId(100000); 250037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe int objClassExpectedHeapId = hasImage() ? 1 : 3; 251037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe if (objectClassHeapId != objClassExpectedHeapId) { 252037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe throw new RuntimeException("Expected object class in heap " + objClassExpectedHeapId + 253037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe " but received " + objectClassHeapId); 254037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe } 255037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe 256037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe A a = new A(); 257037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe extensionTestHolder.add(a); 258037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe setTag(a, 100001); 259037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe System.out.println(getObjectHeapId(100001)); 260037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe 261037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe checkGetObjectHeapIdInCallback(100000, objClassExpectedHeapId); 262037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe checkGetObjectHeapIdInCallback(100001, 3); 263037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe 2648b3ce5ea35ee1a5965a39e9f3762aaa50437ce4dAndreas Gampe long baseTag = 30000000; 2658b3ce5ea35ee1a5965a39e9f3762aaa50437ce4dAndreas Gampe setTag(Object.class, baseTag + objClassExpectedHeapId); 2668b3ce5ea35ee1a5965a39e9f3762aaa50437ce4dAndreas Gampe setTag(Class.class, baseTag + objClassExpectedHeapId); 2678b3ce5ea35ee1a5965a39e9f3762aaa50437ce4dAndreas Gampe Object o = new Object(); 2688b3ce5ea35ee1a5965a39e9f3762aaa50437ce4dAndreas Gampe extensionTestHolder.add(o); 2698b3ce5ea35ee1a5965a39e9f3762aaa50437ce4dAndreas Gampe setTag(o, baseTag + 3); 2708b3ce5ea35ee1a5965a39e9f3762aaa50437ce4dAndreas Gampe 2718b3ce5ea35ee1a5965a39e9f3762aaa50437ce4dAndreas Gampe iterateThroughHeapExt(); 2728b3ce5ea35ee1a5965a39e9f3762aaa50437ce4dAndreas Gampe 273037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe extensionTestHolder = null; 274037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe } 275037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe 2764665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampe private static void runGc() { 277ef3ace09cc19776afcd99e54e12f0b86b8866a7cAndreas Gampe clearStats(); 2788da6d03176651594b821cd3531894c372ca640d5Andreas Gampe forceGarbageCollection(); 2798da6d03176651594b821cd3531894c372ca640d5Andreas Gampe printStats(); 2808da6d03176651594b821cd3531894c372ca640d5Andreas Gampe } 2818da6d03176651594b821cd3531894c372ca640d5Andreas Gampe 282ef3ace09cc19776afcd99e54e12f0b86b8866a7cAndreas Gampe private static void clearStats() { 283ef3ace09cc19776afcd99e54e12f0b86b8866a7cAndreas Gampe getGcStarts(); 284ef3ace09cc19776afcd99e54e12f0b86b8866a7cAndreas Gampe getGcFinishes(); 285ef3ace09cc19776afcd99e54e12f0b86b8866a7cAndreas Gampe } 286ef3ace09cc19776afcd99e54e12f0b86b8866a7cAndreas Gampe 2878da6d03176651594b821cd3531894c372ca640d5Andreas Gampe private static void printStats() { 28870bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe System.out.println("---"); 28970bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe int s = getGcStarts(); 29070bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe int f = getGcFinishes(); 29170bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe System.out.println((s > 0) + " " + (f > 0)); 29270bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe } 29370bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 294037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe private static boolean hasImage() { 295037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe try { 296037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName()); 297037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe BufferedReader reader = new BufferedReader(new FileReader("/proc/" + pid + "/maps")); 298037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe String line; 299037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe while ((line = reader.readLine()) != null) { 300037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe if (line.endsWith(".art")) { 301037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe reader.close(); 302037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe return true; 303037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe } 304037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe } 305037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe reader.close(); 306037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe return false; 307037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe } catch (Exception e) { 308037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe throw new RuntimeException(e); 309037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe } 310037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe } 311037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe 3128a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe private static class TestConfig { 3138a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe private Class<?> klass = null; 3148a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe private int heapFilter = 0; 315c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe private int stopAfter = Integer.MAX_VALUE; 316c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe private int followSet = -1; 31770bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 3188a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe public TestConfig() { 3198a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe } 3208a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe public TestConfig(Class<?> klass, int heapFilter) { 3218a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe this.klass = klass; 3228a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe this.heapFilter = heapFilter; 32370bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe } 324c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe public TestConfig(Class<?> klass, int heapFilter, int stopAfter, int followSet) { 325c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe this.klass = klass; 326c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe this.heapFilter = heapFilter; 327c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe this.stopAfter = stopAfter; 328c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe this.followSet = followSet; 329c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe } 33070bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 3318a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe public void doFollowReferencesTest() throws Exception { 3328a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe // Force GCs to clean up dirt. 3338a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe Runtime.getRuntime().gc(); 3348a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe Runtime.getRuntime().gc(); 33570bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 3368a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe setTag(Thread.currentThread(), 3000); 33770bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 3388a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe { 3398a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe ArrayList<Object> tmpStorage = new ArrayList<>(); 3408a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe doFollowReferencesTestNonRoot(tmpStorage); 3418a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe tmpStorage = null; 3428a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe } 34370bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 3448a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe // Force GCs to clean up dirt. 3458a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe Runtime.getRuntime().gc(); 3468a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe Runtime.getRuntime().gc(); 3475d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 3488a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe doFollowReferencesTestRoot(); 3495d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 3508a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe // Force GCs to clean up dirt. 3518a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe Runtime.getRuntime().gc(); 3528a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe Runtime.getRuntime().gc(); 3538a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe } 35470bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 3558a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe private void doFollowReferencesTestNonRoot(ArrayList<Object> tmpStorage) { 3568a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe Verifier v = new Verifier(); 3578a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe tagClasses(v); 3588a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe A a = createTree(v); 3598a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe tmpStorage.add(a); 3608a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add("0@0", "1@1000"); // tmpStorage[0] --(array-element)--> a. 3615d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 362c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe doFollowReferencesTestImpl(null, stopAfter, followSet, null, v, null); 363c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe doFollowReferencesTestImpl(a.foo2, stopAfter, followSet, null, v, "3@1001"); 36470bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 3658a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe tmpStorage.clear(); 3668a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe } 36770bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 3688a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe private void doFollowReferencesTestRoot() { 3698a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe Verifier v = new Verifier(); 3708a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe tagClasses(v); 3718a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe A a = createTree(v); 37270bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 373c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe doFollowReferencesTestImpl(null, stopAfter, followSet, a, v, null); 374c756f08bdc8bd3ea397b85531f397b2b29cd419bAndreas Gampe doFollowReferencesTestImpl(a.foo2, stopAfter, followSet, a, v, "3@1001"); 3758a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe } 37670bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 3778a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe private void doFollowReferencesTestImpl(A root, int stopAfter, int followSet, 3788a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe Object asRoot, Verifier v, String additionalEnabled) { 3798a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe String[] lines = 3808a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe followReferences(heapFilter, klass, root, stopAfter, followSet, asRoot); 3815d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 3828a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.process(lines, additionalEnabled, heapFilter != 0 || klass != null); 3838a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe } 3845d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 3858a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe private static void tagClasses(Verifier v) { 3868a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe setTag(A.class, 1000); 3875d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 3888a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe setTag(B.class, 1001); 3898a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add("1001@0", "1000@0"); // B.class --(superclass)--> A.class. 3905d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 3918a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe setTag(C.class, 1002); 3928a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add("1002@0", "1001@0"); // C.class --(superclass)--> B.class. 3938a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add("1002@0", "2001@0"); // C.class --(interface)--> I2.class. 3948a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe 3958a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe setTag(I1.class, 2000); 39670bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 3978a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe setTag(I2.class, 2001); 3988a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add("2001@0", "2000@0"); // I2.class --(interface)--> I1.class. 3998a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe } 4008a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe 4018a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe private static A createTree(Verifier v) { 4028a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe A aInst = new A(); 4038a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe setTag(aInst, 1); 4048a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe String aInstStr = "1@1000"; 4058a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe String aClassStr = "1000@0"; 4068a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add(aInstStr, aClassStr); // A -->(class) --> A.class. 4078a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe 4088a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe A a2Inst = new A(); 4098a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe setTag(a2Inst, 2); 4108a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe aInst.foo = a2Inst; 4118a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe String a2InstStr = "2@1000"; 4128a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add(a2InstStr, aClassStr); // A2 -->(class) --> A.class. 4138a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add(aInstStr, a2InstStr); // A -->(field) --> A2. 4148a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe 4158a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe B bInst = new B(); 4168a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe setTag(bInst, 3); 4178a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe aInst.foo2 = bInst; 4188a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe String bInstStr = "3@1001"; 4198a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe String bClassStr = "1001@0"; 4208a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add(bInstStr, bClassStr); // B -->(class) --> B.class. 4218a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add(aInstStr, bInstStr); // A -->(field) --> B. 4228a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe 4238a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe A a3Inst = new A(); 4248a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe setTag(a3Inst, 4); 4258a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe bInst.bar = a3Inst; 4268a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe String a3InstStr = "4@1000"; 4278a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add(a3InstStr, aClassStr); // A3 -->(class) --> A.class. 4288a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add(bInstStr, a3InstStr); // B -->(field) --> A3. 4298a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe 4308a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe C cInst = new C(); 4318a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe setTag(cInst, 5); 4328a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe bInst.bar2 = cInst; 4338a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe String cInstStr = "5@1000"; 4348a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe String cClassStr = "1002@0"; 4358a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add(cInstStr, cClassStr); // C -->(class) --> C.class. 4368a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add(bInstStr, cInstStr); // B -->(field) --> C. 4378a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe 4388a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe A a4Inst = new A(); 4398a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe setTag(a4Inst, 6); 4408a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe cInst.baz = a4Inst; 4418a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe String a4InstStr = "6@1000"; 4428a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add(a4InstStr, aClassStr); // A4 -->(class) --> A.class. 4438a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add(cInstStr, a4InstStr); // C -->(field) --> A4. 4448a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe 4458a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe cInst.baz2 = aInst; 4468a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe v.add(cInstStr, aInstStr); // C -->(field) --> A. 4478a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe 4481dfd10ec49a0734d4f533a7cc2950102fbbbff89Andreas Gampe A[] aArray = new A[2]; 4491dfd10ec49a0734d4f533a7cc2950102fbbbff89Andreas Gampe setTag(aArray, 500); 4501dfd10ec49a0734d4f533a7cc2950102fbbbff89Andreas Gampe aArray[1] = a2Inst; 4511dfd10ec49a0734d4f533a7cc2950102fbbbff89Andreas Gampe cInst.array = aArray; 4521dfd10ec49a0734d4f533a7cc2950102fbbbff89Andreas Gampe String aArrayStr = "500@0"; 4531dfd10ec49a0734d4f533a7cc2950102fbbbff89Andreas Gampe v.add(cInstStr, aArrayStr); 4541dfd10ec49a0734d4f533a7cc2950102fbbbff89Andreas Gampe v.add(aArrayStr, a2InstStr); 4551dfd10ec49a0734d4f533a7cc2950102fbbbff89Andreas Gampe 4568a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe return aInst; 4578a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe } 45870bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe } 45970bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 46070bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public static class A { 46170bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public A foo; 46270bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public A foo2; 46370bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 46470bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public A() {} 46570bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public A(A a, A b) { 46670bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe foo = a; 46770bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe foo2 = b; 46870bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe } 46970bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe } 47070bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 47170bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public static class B extends A { 47270bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public A bar; 47370bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public A bar2; 47470bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 47570bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public B() {} 47670bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public B(A a, A b) { 47770bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe bar = a; 47870bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe bar2 = b; 47970bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe } 48070bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe } 48170bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 48270bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public static interface I1 { 48370bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public final static int i1Field = 1; 48470bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe } 48570bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 48670bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public static interface I2 extends I1 { 48770bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public final static int i2Field = 2; 48870bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe } 48970bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 49070bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public static class C extends B implements I2 { 49170bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public A baz; 49270bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public A baz2; 4931dfd10ec49a0734d4f533a7cc2950102fbbbff89Andreas Gampe public A[] array; 49470bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 49570bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public C() {} 49670bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe public C(A a, A b) { 49770bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe baz = a; 49870bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe baz2 = b; 49970bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe } 5008da6d03176651594b821cd3531894c372ca640d5Andreas Gampe } 5018da6d03176651594b821cd3531894c372ca640d5Andreas Gampe 502e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe private static interface Inf1 { 503e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe public final static int A = 1; 504e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe } 505e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 506e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe private static interface Inf2 extends Inf1 { 507e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe public final static int B = 1; 508e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe } 509e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 510e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe private static class IntObject implements Inf1 { 511e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe byte b = (byte)1; 512e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe char c= 'a'; 513e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe short s = (short)2; 514e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe int i = 3; 515e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe long l = 4; 516e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe Object o = new Object(); 517e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe static int sI = 5; 518e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe } 519e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 520e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe private static class FloatObject extends IntObject implements Inf2 { 521e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe float f = 1.23f; 522e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe double d = 1.23; 523e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe Object p = new Object(); 524e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe static int sI = 6; 525e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe } 526e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe 5275d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe public static class Verifier { 52858982d596d210dd93999826f5027f6583a0905ccAndreas Gampe // Should roots with vreg=-1 be printed? 52958982d596d210dd93999826f5027f6583a0905ccAndreas Gampe public final static boolean PRINT_ROOTS_WITH_UNKNOWN_VREG = false; 53058982d596d210dd93999826f5027f6583a0905ccAndreas Gampe 5315d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe public static class Node { 5325d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe public String referrer; 5335d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 5345d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe public HashSet<String> referrees = new HashSet<>(); 5355d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 5365d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe public Node(String r) { 5375d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe referrer = r; 5385d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 5395d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 5405d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe public boolean isRoot() { 5415d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe return referrer.startsWith("root@"); 5425d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 5435d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 5445d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 5455d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe HashMap<String, Node> nodes = new HashMap<>(); 5465d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 5475d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe public Verifier() { 5485d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 5495d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 5505d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe public void add(String referrer, String referree) { 5515d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe if (!nodes.containsKey(referrer)) { 5525d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe nodes.put(referrer, new Node(referrer)); 5535d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 5545d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe if (referree != null) { 5555d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe nodes.get(referrer).referrees.add(referree); 5565d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 5575d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 5585d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 5598a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe public void process(String[] lines, String additionalEnabledReferrer, boolean filtered) { 5605d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe // This method isn't optimal. The loops could be merged. However, it's more readable if 5615d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe // the different parts are separated. 5625d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 5635d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe ArrayList<String> rootLines = new ArrayList<>(); 5645d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe ArrayList<String> nonRootLines = new ArrayList<>(); 5655d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 5665d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe // Check for consecutive chunks of referrers. Also ensure roots come first. 5675d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe { 5685d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe String currentHead = null; 5695d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe boolean rootsDone = false; 5705d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe HashSet<String> completedReferrers = new HashSet<>(); 5715d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe for (String l : lines) { 5725d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe String referrer = getReferrer(l); 5735d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 5745d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe if (isRoot(referrer)) { 5755d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe if (rootsDone) { 5765d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe System.out.println("ERROR: Late root " + l); 5775d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe print(lines); 5785d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe return; 5795d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 5805d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe rootLines.add(l); 5815d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe continue; 5825d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 5835d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 5845d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe rootsDone = true; 5855d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 5865d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe if (currentHead == null) { 5875d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe currentHead = referrer; 5885d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } else { 589e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe // Ignore 0@0, as it can happen at any time (as it stands for all other objects). 590e0f8ed966a22834815c8ec1a9ddbf0bfd35865eaAndreas Gampe if (!currentHead.equals(referrer) && !referrer.equals("0@0")) { 5915d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe completedReferrers.add(currentHead); 5925d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe currentHead = referrer; 5935d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe if (completedReferrers.contains(referrer)) { 5945d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe System.out.println("Non-contiguous referrer " + l); 5955d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe print(lines); 5965d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe return; 5975d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 5985d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 5995d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6005d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe nonRootLines.add(l); 6015d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6025d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6035d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 6045d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe // Sort (root order is not specified) and print the roots. 6055d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe // TODO: What about extra roots? JNI and the interpreter seem to introduce those (though it 6065d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe // isn't clear why a debuggable-AoT test doesn't have the same, at least for locals). 6075d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe // For now, swallow duplicates, and resolve once we have the metadata for the roots. 6085d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe { 6095d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe Collections.sort(rootLines); 6105d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe String lastRoot = null; 6115d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe for (String l : rootLines) { 6125d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe if (lastRoot != null && lastRoot.equals(l)) { 6135d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe continue; 6145d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6155d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe lastRoot = l; 61658982d596d210dd93999826f5027f6583a0905ccAndreas Gampe if (!PRINT_ROOTS_WITH_UNKNOWN_VREG && l.indexOf("vreg=-1") > 0) { 61758982d596d210dd93999826f5027f6583a0905ccAndreas Gampe continue; 61858982d596d210dd93999826f5027f6583a0905ccAndreas Gampe } 6195d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe System.out.println(l); 6205d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6215d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6225d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 6238a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe if (filtered) { 6248a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe // If we aren't tracking dependencies, just sort the lines and print. 6258a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe // TODO: As the verifier is currently using the output lines to track dependencies, we 6268a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe // cannot verify that output is correct when parts of it are suppressed by filters. 6278a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe // To correctly track this we need to take node information into account, and 6288a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe // actually analyze the graph. 6298a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe Collections.sort(nonRootLines); 6308a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe for (String l : nonRootLines) { 6318a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe System.out.println(l); 6328a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe } 6338a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe 6348a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe System.out.println("---"); 6358a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe return; 6368a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe } 6378a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe 6385d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe // Iterate through the lines, keeping track of which referrers are visited, to ensure the 6395d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe // order is acceptable. 6405d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe HashSet<String> enabled = new HashSet<>(); 6415d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe if (additionalEnabledReferrer != null) { 6425d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe enabled.add(additionalEnabledReferrer); 6435d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6445d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe // Always add "0@0". 6455d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe enabled.add("0@0"); 6465d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 6475d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe for (String l : lines) { 6485d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe String referrer = getReferrer(l); 6495d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe String referree = getReferree(l); 6505d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe if (isRoot(referrer)) { 6515d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe // For a root src, just enable the referree. 6525d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe enabled.add(referree); 6535d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } else { 6545d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe // Check that the referrer is enabled (may be visited). 6555d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe if (!enabled.contains(referrer)) { 6565d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe System.out.println("Referrer " + referrer + " not enabled: " + l); 6575d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe print(lines); 6585d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe return; 6595d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6605d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe enabled.add(referree); 6615d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6625d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6635d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 6645d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe // Now just sort the non-root lines and output them 6655d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe Collections.sort(nonRootLines); 6665d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe for (String l : nonRootLines) { 6675d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe System.out.println(l); 6685d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6695d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 6705d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe System.out.println("---"); 6715d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6725d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 6735d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe public static boolean isRoot(String ref) { 6745d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe return ref.startsWith("root@"); 6755d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6765d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 6775d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe private static String getReferrer(String line) { 6785d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe int i = line.indexOf(" --"); 6795d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe if (i <= 0) { 6805d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe throw new IllegalArgumentException(line); 6815d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6825d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe int j = line.indexOf(' '); 6835d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe if (i != j) { 6845d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe throw new IllegalArgumentException(line); 6855d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6865d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe return line.substring(0, i); 6875d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6885d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 6895d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe private static String getReferree(String line) { 6905d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe int i = line.indexOf("--> "); 6915d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe if (i <= 0) { 6925d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe throw new IllegalArgumentException(line); 6935d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6945d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe int j = line.indexOf(' ', i + 4); 6955d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe if (j < 0) { 6965d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe throw new IllegalArgumentException(line); 6975d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 6985d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe return line.substring(i + 4, j); 6995d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 7005d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 7015d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe private static void print(String[] lines) { 7025d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe for (String l : lines) { 7035d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe System.out.println(l); 7045d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 7055d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 7065d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe } 7075d139fc3898bad69b95a5e8583e4a7b2cc00c0b0Andreas Gampe 7084665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampe private static void setTag(Object o, long tag) { 7094665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampe Main.setTag(o, tag); 7104665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampe } 7114665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampe private static long getTag(Object o) { 7124665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampe return Main.getTag(o); 7134665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampe } 7144665167ddc34008dfa78a2873685fe7a98772eabAndreas Gampe 7158da6d03176651594b821cd3531894c372ca640d5Andreas Gampe private static native void setupGcCallback(); 7168da6d03176651594b821cd3531894c372ca640d5Andreas Gampe private static native void enableGcTracking(boolean enable); 7178da6d03176651594b821cd3531894c372ca640d5Andreas Gampe private static native int getGcStarts(); 7188da6d03176651594b821cd3531894c372ca640d5Andreas Gampe private static native int getGcFinishes(); 7198da6d03176651594b821cd3531894c372ca640d5Andreas Gampe private static native void forceGarbageCollection(); 72070bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe 721037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe private static native void checkForExtensionApis(); 722037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe private static native int getObjectHeapId(long tag); 723037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe private static native String getHeapName(int heapId); 724037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe private static native void checkGetObjectHeapIdInCallback(long tag, int heapId); 725037b8b7503ce47dd39d554e85a0bcb904c9f2127Andreas Gampe 7268a5550dc29a69a5b3e246385bfe1c4cf26b9f39aAndreas Gampe public static native String[] followReferences(int heapFilter, Class<?> klassFilter, 72770bfc8a5783044762cab864fc0ba26d9cc821ee3Andreas Gampe Object initialObject, int stopAfter, int followSet, Object jniRef); 7283ec8e40930c87be425a4e74d6a617b6396cfe003Andreas Gampe public static native String[] followReferencesString(Object initialObject); 729becd6addfe1cb8326cc8ada5828c83f201124797Andreas Gampe public static native String followReferencesPrimitiveArray(Object initialObject); 730e731693fd63bfa7d528d8aeaccc1118b920af1dbAndreas Gampe public static native String followReferencesPrimitiveFields(Object initialObject); 7318b3ce5ea35ee1a5965a39e9f3762aaa50437ce4dAndreas Gampe 7328b3ce5ea35ee1a5965a39e9f3762aaa50437ce4dAndreas Gampe private static native void iterateThroughHeapExt(); 7338da6d03176651594b821cd3531894c372ca640d5Andreas Gampe} 734