1 /* 2 * Copyright (C) 2015 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 java.lang.ref.PhantomReference; 18 import java.lang.ref.ReferenceQueue; 19 import java.lang.ref.SoftReference; 20 import java.lang.ref.WeakReference; 21 import libcore.util.NativeAllocationRegistry; 22 import android.graphics.Bitmap; 23 24 // We take a heap dump that includes a single instance of this 25 // DumpedStuff class. Objects stored as fields in this class can be easily 26 // found in the hprof dump by searching for the instance of the DumpedStuff 27 // class and reading the desired field. 28 public class DumpedStuff extends SuperDumpedStuff { allocateObjectAtKnownSite()29 private void allocateObjectAtKnownSite() { 30 objectAllocatedAtKnownSite = new Object(); 31 allocateObjectAtKnownSubSite(); 32 allocateObjectAtObfSuperSite(); 33 allocateObjectAtUnObfSuperSite(); 34 allocateObjectAtOverriddenSite(); 35 } 36 allocateObjectAtKnownSubSite()37 private void allocateObjectAtKnownSubSite() { 38 objectAllocatedAtKnownSubSite = new Object(); 39 } 40 allocateObjectAtOverriddenSite()41 public void allocateObjectAtOverriddenSite() { 42 objectAllocatedAtOverriddenSite = new Object(); 43 } 44 DumpedStuff(boolean baseline)45 DumpedStuff(boolean baseline) { 46 allocateObjectAtKnownSite(); 47 48 int n = baseline ? 400000 : 1000000; 49 bigArray = new byte[n]; 50 for (int i = 0; i < n; i++) { 51 bigArray[i] = (byte)((i * i) & 0xFF); 52 } 53 54 // 0x12345, 50000, and 0xABCDABCD are arbitrary values. 55 NativeAllocationRegistry registry = new NativeAllocationRegistry( 56 Main.class.getClassLoader(), 0x12345, 50000); 57 registry.registerNativeAllocation(anObject, 0xABCDABCD); 58 59 { 60 Object object = new Object(); 61 aLongStrongPathToSamplePathObject = new Reference(new Reference(new Reference(object))); 62 aShortWeakPathToSamplePathObject = new WeakReference(new Reference(object)); 63 } 64 65 addedObject = baseline ? null : new AddedObject(); 66 removedObject = baseline ? new RemovedObject() : null; 67 modifiedObject = new ModifiedObject(); 68 modifiedObject.value = baseline ? 5 : 8; 69 modifiedObject.modifiedRefField = baseline ? "A1" : "A2"; 70 modifiedObject.unmodifiedRefField = "B"; 71 modifiedStaticField = baseline ? "C1" : "C2"; 72 modifiedArray = baseline ? new int[]{0, 1, 2, 3} : new int[]{3, 1, 2, 0}; 73 74 // Deep matching dominator trees shouldn't smash the stack when we try 75 // to diff them. Make some deep dominator trees to help test it. 76 for (int i = 0; i < 10000; i++) { 77 StackSmasher smasher = new StackSmasher(); 78 smasher.child = stackSmasher; 79 stackSmasher = smasher; 80 81 if (!baseline) { 82 smasher = new StackSmasher(); 83 smasher.child = stackSmasherAdded; 84 stackSmasherAdded = smasher; 85 } 86 } 87 88 gcPathArray[2].right.left = gcPathArray[2].left.right; 89 90 bitmapOne = new Bitmap(100, 200, 0xDEADBEEF, bigArray); 91 bitmapTwo = new Bitmap(100, 200, 0xBEEFDEAD, bigArray); 92 } 93 94 public static class ObjectTree { 95 public ObjectTree left; 96 public ObjectTree right; 97 ObjectTree(ObjectTree left, ObjectTree right)98 public ObjectTree(ObjectTree left, ObjectTree right) { 99 this.left = left; 100 this.right = right; 101 } 102 } 103 104 public static class AddedObject { 105 } 106 107 public static class RemovedObject { 108 } 109 110 public static class UnchangedObject { 111 } 112 113 public static class ModifiedObject { 114 public int value; 115 public String modifiedRefField; 116 public String unmodifiedRefField; 117 } 118 119 public static class StackSmasher { 120 public StackSmasher child; 121 } 122 123 public static class Reference { 124 public Object referent; 125 Reference(Object referent)126 public Reference(Object referent) { 127 this.referent = referent; 128 } 129 } 130 131 public interface IDumpedManager { 132 public static class Stub extends android.os.Binder implements IDumpedManager { 133 private static final java.lang.String DESCRIPTOR = "DumpedStuff$IDumpedManager"; Stub()134 public Stub() { 135 super(DESCRIPTOR); 136 } 137 public static class Proxy implements IDumpedManager { 138 android.os.IBinder mRemote; Proxy(android.os.IBinder binderProxy)139 Proxy(android.os.IBinder binderProxy) { 140 mRemote = binderProxy; 141 } 142 } 143 } 144 } 145 146 public interface IBinderInterfaceImpostor { 147 public static class Stub { 148 public static class Proxy implements IBinderInterfaceImpostor { 149 android.os.IBinder mFakeRemote = new android.os.BinderProxy(); Proxy(android.os.IBinder binderProxy)150 Proxy(android.os.IBinder binderProxy) { 151 mFakeRemote = binderProxy; 152 } 153 } 154 } 155 } 156 157 private static class BinderProxyCarrier { 158 android.os.IBinder mRemote; BinderProxyCarrier(android.os.IBinder binderProxy)159 BinderProxyCarrier(android.os.IBinder binderProxy) { 160 mRemote = binderProxy; 161 } 162 } 163 164 private static class BinderService extends IDumpedManager.Stub { 165 // Intentionally empty 166 }; 167 168 private static class FakeBinderService extends IBinderInterfaceImpostor.Stub { 169 // Intentionally empty 170 }; 171 172 public String basicString = "hello, world"; 173 public String nonAscii = "Sigma (Ʃ) is not ASCII"; 174 public String embeddedZero = "embedded\0..."; // Non-ASCII for string compression purposes. 175 public char[] charArray = "char thing".toCharArray(); 176 public String nullString = null; 177 public Object anObject = new Object(); 178 public Reference aReference = new Reference(anObject); 179 public ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>(); 180 public PhantomReference aPhantomReference = new PhantomReference(anObject, referenceQueue); 181 public WeakReference aWeakReference = new WeakReference(anObject, referenceQueue); 182 public WeakReference aNullReferentReference = new WeakReference(null, referenceQueue); 183 public SoftReference aSoftReference = new SoftReference(new Object()); 184 public Reference reachabilityReferenceChain; 185 public byte[] bigArray; 186 public Bitmap bitmapOne = null; 187 public Bitmap bitmapTwo = null; 188 public ObjectTree[] gcPathArray = new ObjectTree[]{null, null, 189 new ObjectTree( 190 new ObjectTree(null, new ObjectTree(null, null)), 191 new ObjectTree(null, null)), 192 null}; 193 public Reference aLongStrongPathToSamplePathObject; 194 public WeakReference aShortWeakPathToSamplePathObject; 195 public WeakReference aWeakRefToGcRoot = new WeakReference(Main.class); 196 public SoftReference aSoftChain = new SoftReference(new Reference(new Reference(new Object()))); 197 public Object[] basicStringRef; 198 public AddedObject addedObject; 199 public UnchangedObject unchangedObject = new UnchangedObject(); 200 public RemovedObject removedObject; 201 public ModifiedObject modifiedObject; 202 public StackSmasher stackSmasher; 203 public StackSmasher stackSmasherAdded; 204 public static String modifiedStaticField; 205 public int[] modifiedArray; 206 public Object objectAllocatedAtKnownSite; 207 public Object objectAllocatedAtKnownSubSite; 208 public android.os.IBinder correctBinderProxy = new android.os.BinderProxy(); 209 public android.os.IBinder imposedBinderProxy = new android.os.BinderProxy(); 210 public android.os.IBinder carriedBinderProxy = new android.os.BinderProxy(); 211 Object correctBinderProxyObject = new IDumpedManager.Stub.Proxy(correctBinderProxy); 212 Object impostorBinderProxyObject = new IBinderInterfaceImpostor.Stub.Proxy(imposedBinderProxy); 213 Object carrierBinderProxyObject = new BinderProxyCarrier(carriedBinderProxy); 214 215 Object binderService = new BinderService(); 216 Object fakeBinderService = new FakeBinderService(); 217 Object binderToken = new android.os.Binder(); 218 Object namedBinderToken = new android.os.Binder("awesomeToken"); 219 220 // Allocate those objects that we need to not be GC'd before taking the heap 221 // dump. shouldNotGc()222 public void shouldNotGc() { 223 reachabilityReferenceChain = new Reference( 224 new SoftReference( 225 new Reference( 226 new WeakReference( 227 new SoftReference( 228 new PhantomReference(new Object(), referenceQueue)))))); 229 } 230 } 231