• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.android.ahat;
18 
19 import com.android.tools.perflib.heap.ClassObj;
20 import com.android.tools.perflib.heap.Instance;
21 import java.net.URI;
22 
23 /**
24  * Class to render an hprof value to a DocString.
25  */
26 class Value {
27 
28   // For string literals, we limit the number of characters we show to
29   // kMaxChars in case the string is really long.
30   private static int kMaxChars = 200;
31 
32   /**
33    * Create a DocString representing a summary of the given instance.
34    */
renderInstance(AhatSnapshot snapshot, Instance inst)35   private static DocString renderInstance(AhatSnapshot snapshot, Instance inst) {
36     DocString formatted = new DocString();
37     if (inst == null) {
38       formatted.append("(null)");
39       return formatted;
40     }
41 
42     // Annotate roots as roots.
43     if (snapshot.isRoot(inst)) {
44       formatted.append("(root) ");
45     }
46 
47 
48     // Annotate classes as classes.
49     DocString link = new DocString();
50     if (inst instanceof ClassObj) {
51       link.append("class ");
52     }
53 
54     link.append(inst.toString());
55 
56     URI objTarget = DocString.formattedUri("object?id=%d", inst.getId());
57     formatted.appendLink(objTarget, link);
58 
59     // Annotate Strings with their values.
60     String stringValue = InstanceUtils.asString(inst, kMaxChars);
61     if (stringValue != null) {
62       formatted.appendFormat(" \"%s", stringValue);
63       formatted.append(kMaxChars == stringValue.length() ? "..." : "\"");
64     }
65 
66     // Annotate Reference with its referent
67     Instance referent = InstanceUtils.getReferent(inst);
68     if (referent != null) {
69       formatted.append(" for ");
70 
71       // It should not be possible for a referent to refer back to the
72       // reference object, even indirectly, so there shouldn't be any issues
73       // with infinite recursion here.
74       formatted.append(renderInstance(snapshot, referent));
75     }
76 
77     // Annotate DexCache with its location.
78     String dexCacheLocation = InstanceUtils.getDexCacheLocation(inst, kMaxChars);
79     if (dexCacheLocation != null) {
80       formatted.appendFormat(" for %s", dexCacheLocation);
81       if (kMaxChars == dexCacheLocation.length()) {
82         formatted.append("...");
83       }
84     }
85 
86 
87     // Annotate bitmaps with a thumbnail.
88     Instance bitmap = InstanceUtils.getAssociatedBitmapInstance(inst);
89     String thumbnail = "";
90     if (bitmap != null) {
91       URI uri = DocString.formattedUri("bitmap?id=%d", bitmap.getId());
92       formatted.appendThumbnail(uri, "bitmap image");
93     }
94     return formatted;
95   }
96 
97   /**
98    * Create a DocString summarizing the given value.
99    */
render(AhatSnapshot snapshot, Object val)100   public static DocString render(AhatSnapshot snapshot, Object val) {
101     if (val instanceof Instance) {
102       return renderInstance(snapshot, (Instance)val);
103     } else {
104       return DocString.format("%s", val);
105     }
106   }
107 }
108