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 { allocateObjectAtKnownSite()28 private void allocateObjectAtKnownSite() { 29 objectAllocatedAtKnownSite = new Object(); 30 allocateObjectAtKnownSubSite(); 31 allocateObjectAtObfSuperSite(); 32 allocateObjectAtUnObfSuperSite(); 33 allocateObjectAtOverriddenSite(); 34 } 35 allocateObjectAtKnownSubSite()36 private void allocateObjectAtKnownSubSite() { 37 objectAllocatedAtKnownSubSite = new Object(); 38 } 39 allocateObjectAtOverriddenSite()40 public void allocateObjectAtOverriddenSite() { 41 objectAllocatedAtOverriddenSite = new Object(); 42 } 43 DumpedStuff(boolean baseline)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 ObjectTree(ObjectTree left, ObjectTree right)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 Reference(Object referent)122 public Reference(Object referent) { 123 this.referent = referent; 124 } 125 } 126 127 public String basicString = "hello, world"; 128 public String nonAscii = "Sigma (Ʃ) is not ASCII"; 129 public String embeddedZero = "embedded\0..."; // Non-ASCII for string compression purposes. 130 public char[] charArray = "char thing".toCharArray(); 131 public String nullString = null; 132 public Object anObject = new Object(); 133 public Reference aReference = new Reference(anObject); 134 public ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>(); 135 public PhantomReference aPhantomReference = new PhantomReference(anObject, referenceQueue); 136 public WeakReference aWeakReference = new WeakReference(anObject, referenceQueue); 137 public WeakReference aNullReferentReference = new WeakReference(null, referenceQueue); 138 public SoftReference aSoftReference = new SoftReference(new Object()); 139 public byte[] bigArray; 140 public ObjectTree[] gcPathArray = new ObjectTree[]{null, null, 141 new ObjectTree( 142 new ObjectTree(null, new ObjectTree(null, null)), 143 new ObjectTree(null, null)), 144 null}; 145 public Reference aLongStrongPathToSamplePathObject; 146 public WeakReference aShortWeakPathToSamplePathObject; 147 public WeakReference aWeakRefToGcRoot = new WeakReference(Main.class); 148 public SoftReference aWeakChain = new SoftReference(new Reference(new Reference(new Object()))); 149 public Object[] basicStringRef; 150 public AddedObject addedObject; 151 public UnchangedObject unchangedObject = new UnchangedObject(); 152 public RemovedObject removedObject; 153 public ModifiedObject modifiedObject; 154 public StackSmasher stackSmasher; 155 public StackSmasher stackSmasherAdded; 156 public static String modifiedStaticField; 157 public int[] modifiedArray; 158 public Object objectAllocatedAtKnownSite; 159 public Object objectAllocatedAtKnownSubSite; 160 } 161