Home | History | Annotate | Download | only in test-dump
      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