1 /*
2  * Copyright (C) 2017 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 package com.android.ahat;
18 
19 import com.android.ahat.heapdump.AhatInstance;
20 import com.android.ahat.heapdump.AhatSnapshot;
21 import com.android.ahat.heapdump.Reachability;
22 import com.android.ahat.heapdump.Site;
23 import java.io.IOException;
24 import org.junit.Test;
25 
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertNotSame;
28 import static org.junit.Assert.assertSame;
29 
30 public class SiteTest {
31   @Test
objectsAllocatedAtKnownSites()32   public void objectsAllocatedAtKnownSites() throws IOException {
33     TestDump dump = TestDump.getTestDump();
34     AhatSnapshot snapshot = dump.getAhatSnapshot();
35 
36     AhatInstance oKnownSite = dump.getDumpedAhatInstance("objectAllocatedAtKnownSite");
37     Site sKnownSite = oKnownSite.getSite();
38     assertEquals("DumpedStuff.java", sKnownSite.getFilename());
39     assertEquals("allocateObjectAtKnownSite", sKnownSite.getMethodName());
40     assertEquals(29, sKnownSite.getLineNumber());
41     assertSame(sKnownSite, snapshot.getSite(sKnownSite.getId()));
42 
43     AhatInstance oKnownSubSite = dump.getDumpedAhatInstance("objectAllocatedAtKnownSubSite");
44     Site sKnownSubSite = oKnownSubSite.getSite();
45     assertEquals("DumpedStuff.java", sKnownSubSite.getFilename());
46     assertEquals("allocateObjectAtKnownSubSite", sKnownSubSite.getMethodName());
47     assertEquals(37, sKnownSubSite.getLineNumber());
48     assertSame(sKnownSubSite, snapshot.getSite(sKnownSubSite.getId()));
49 
50     Site sKnownSubSiteParent = sKnownSubSite.getParent();
51     assertEquals("DumpedStuff.java", sKnownSubSiteParent.getFilename());
52     assertEquals("allocateObjectAtKnownSite", sKnownSubSiteParent.getMethodName());
53     assertEquals(30, sKnownSubSiteParent.getLineNumber());
54     assertSame(sKnownSubSiteParent, snapshot.getSite(sKnownSubSiteParent.getId()));
55 
56     assertNotSame(sKnownSite, sKnownSubSiteParent);
57     assertSame(sKnownSite.getParent(), sKnownSubSiteParent.getParent());
58 
59     Site sKnownSiteParent = sKnownSite.getParent();
60     assertEquals("DumpedStuff.java", sKnownSiteParent.getFilename());
61     assertEquals("<init>", sKnownSiteParent.getMethodName());
62     assertEquals(45, sKnownSiteParent.getLineNumber());
63     assertSame(sKnownSiteParent, snapshot.getSite(sKnownSiteParent.getId()));
64 
65     AhatInstance oObfSuperSite = dump.getDumpedAhatInstance("objectAllocatedAtObfSuperSite");
66     Site sObfSuperSite = oObfSuperSite.getSite();
67     assertEquals("SuperDumpedStuff.java", sObfSuperSite.getFilename());
68     assertEquals("allocateObjectAtObfSuperSite", sObfSuperSite.getMethodName());
69     assertEquals(22, sObfSuperSite.getLineNumber());
70     assertSame(sObfSuperSite, snapshot.getSite(sObfSuperSite.getId()));
71 
72     AhatInstance oUnObfSuperSite = dump.getDumpedAhatInstance("objectAllocatedAtUnObfSuperSite");
73     Site sUnObfSuperSite = oUnObfSuperSite.getSite();
74     assertEquals("SuperDumpedStuff.java", sUnObfSuperSite.getFilename());
75     assertEquals("allocateObjectAtUnObfSuperSite", sUnObfSuperSite.getMethodName());
76     assertEquals(26, sUnObfSuperSite.getLineNumber());
77     assertSame(sUnObfSuperSite, snapshot.getSite(sUnObfSuperSite.getId()));
78 
79     AhatInstance oOverriddenSite = dump.getDumpedAhatInstance("objectAllocatedAtOverriddenSite");
80     Site sOverriddenSite = oOverriddenSite.getSite();
81     assertEquals("DumpedStuff.java", sOverriddenSite.getFilename());
82     assertEquals("allocateObjectAtOverriddenSite", sOverriddenSite.getMethodName());
83     assertEquals(41, sOverriddenSite.getLineNumber());
84     assertSame(sOverriddenSite, snapshot.getSite(sOverriddenSite.getId()));
85   }
86 
87   @Test
objectsInfos()88   public void objectsInfos() throws IOException {
89     // Verify that objectsInfos only include counts for --retained instances.
90     // We do this by counting the number of 'Reference' instances allocated at
91     // the Site where reachabilityReferenceChain is allocated in DumpedStuff:
92     //
93     // reachabilityReferenceChain = new Reference(
94     //     new SoftReference(
95     //     new Reference(
96     //     new WeakReference(
97     //     new SoftReference(
98     //     new PhantomReference(new Object(), referenceQueue))))));
99     //
100     // The first instance of 'Reference' is strongly reachable, the second is
101     // softly reachable. So if --retained is 'strong', we should see just the
102     // one reference, but if --retained is 'soft', we should see both of them.
103 
104     TestDump dumpStrong = TestDump.getTestDump("test-dump.hprof",
105                                                "test-dump-base.hprof",
106                                                "test-dump.map",
107                                                Reachability.STRONG);
108 
109     AhatInstance refStrong = dumpStrong.getDumpedAhatInstance("reachabilityReferenceChain");
110     Site siteStrong = refStrong.getSite();
111     long numReferenceStrong = 0;
112     for (Site.ObjectsInfo info : siteStrong.getObjectsInfos()) {
113       if (info.heap == refStrong.getHeap() && info.classObj == refStrong.getClassObj()) {
114         numReferenceStrong = info.numInstances;
115         break;
116       }
117     }
118     assertEquals(1, numReferenceStrong);
119 
120     TestDump dumpSoft = TestDump.getTestDump("test-dump.hprof",
121                                              "test-dump-base.hprof",
122                                              "test-dump.map",
123                                              Reachability.SOFT);
124     AhatInstance refSoft = dumpSoft.getDumpedAhatInstance("reachabilityReferenceChain");
125     Site siteSoft = refSoft.getSite();
126     long numReferenceSoft = 0;
127     for (Site.ObjectsInfo info : siteSoft.getObjectsInfos()) {
128       if (info.heap == refSoft.getHeap() && info.classObj == refSoft.getClassObj()) {
129         numReferenceSoft = info.numInstances;
130         break;
131       }
132     }
133     assertEquals(2, numReferenceSoft);
134   }
135 }
136