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