OSDN Git Service

Clean up ref table dump
authorAndy McFadden <fadden@android.com>
Wed, 16 Mar 2011 00:04:42 +0000 (17:04 -0700)
committerAndy McFadden <fadden@android.com>
Wed, 16 Mar 2011 00:13:24 +0000 (17:13 -0700)
We were using the in-heap size as a sort key and a display item,
but the sizes of objects aren't all that interesting -- usually,
if the table is being dumped, it's because we ran into an object
count limitation rather than a total size limitation.

This largely eliminates the display of object sizes.  We show array
element counts for array objects.

Bug 3447435

Change-Id: I3bf31ed45317336ce9a41f058cce8eba88e58cc8

vm/ReferenceTable.c

index 20d4d46..0e70c0d 100644 (file)
@@ -151,6 +151,18 @@ bool dvmRemoveFromReferenceTable(ReferenceTable* pRef, Object** bottom,
 }
 
 /*
+ * If "obj" is an array, return the number of elements in the array.
+ * Otherwise, return zero.
+ */
+static size_t getElementCount(const Object* obj)
+{
+    const ArrayObject* arrayObj = (ArrayObject*) obj;
+    if (arrayObj == NULL || arrayObj->obj.clazz == NULL || !dvmIsArray(arrayObj))
+        return 0;
+    return arrayObj->length;
+}
+
+/*
  * This is a qsort() callback.  We sort Object* by class, allocation size,
  * and then by the Object* itself.
  */
@@ -173,10 +185,10 @@ static int compareObject(const void* vobj1, const void* vobj2)
     if (obj1->clazz != obj2->clazz) {
         return (u1*)obj1->clazz - (u1*)obj2->clazz;
     } else {
-        int size1 = dvmObjectSizeInHeap(obj1);
-        int size2 = dvmObjectSizeInHeap(obj2);
-        if (size1 != size2) {
-            return size1 - size2;
+        size_t count1 = getElementCount(obj1);
+        size_t count2 = getElementCount(obj2);
+        if (count1 != count2) {
+            return count1 - count2;
         } else {
             return (u1*)obj1 - (u1*)obj2;
         }
@@ -186,10 +198,11 @@ static int compareObject(const void* vobj1, const void* vobj2)
 /*
  * Log an object with some additional info.
  *
- * Pass in the number of additional elements that are identical to or
- * equivalent to the original.
+ * Pass in the number of elements in the array (or 0 if this is not an
+ * array object), and the number of additional objects that are identical
+ * or equivalent to the original.
  */
-static void logObject(const Object* obj, int size, int identical, int equiv)
+static void logObject(const Object* obj, size_t elems, int identical, int equiv)
 {
     if (obj == NULL) {
         LOGW("  NULL reference (count=%d)\n", equiv);
@@ -200,11 +213,19 @@ static void logObject(const Object* obj, int size, int identical, int equiv)
     const char* descriptor =
         (obj->clazz != NULL) ? obj->clazz->descriptor : "(raw)";
 
+    char elemStr[16];
+
+    if (elems != 0) {
+        snprintf(elemStr, sizeof(elemStr), " [%zd]", elems);
+    } else {
+        elemStr[0] = '\0';
+    }
+
     if (identical + equiv != 0) {
-        LOGW("%5d of %s %dB (%d unique)\n", identical + equiv +1,
-            descriptor, size, equiv +1);
+        LOGW("%5d of %s%s (%d unique)\n", identical + equiv +1,
+            descriptor, elemStr, equiv +1);
     } else {
-        LOGW("%5d of %s %dB\n", identical + equiv +1, descriptor, size);
+        LOGW("%5d of %s%s\n", identical + equiv +1, descriptor, elemStr);
     }
 }
 
@@ -217,39 +238,41 @@ static void logObject(const Object* obj, int size, int identical, int equiv)
 void dvmDumpReferenceTableContents(Object* const* refs, size_t count,
     const char* descr)
 {
-    const size_t kLast = 10;
-
     if (count == 0) {
         LOGW("%s reference table has no entries\n", descr);
         return;
     }
-    assert(count > 0);
 
     /*
      * Dump the most recent N entries.
      */
+    const size_t kLast = 10;
     LOGW("Last %d entries in %s reference table:\n", kLast, descr);
-    size_t size, idx;
     int start = count - kLast;
     if (start < 0)
         start = 0;
 
+    size_t idx, elems;
     for (idx = start; idx < count; idx++) {
-        if (refs[idx] == NULL)
-            continue;
-        size = dvmObjectSizeInHeap(refs[idx]);
         const Object* ref = refs[idx];
-        if (ref->clazz == gDvm.classJavaLangClass) {
-            ClassObject* clazz = (ClassObject*) ref;
-            LOGW("%5d: %p cls=%s '%s' (%d bytes)\n", idx, ref,
-                (refs[idx] == NULL) ? "-" : ref->clazz->descriptor,
-                clazz->descriptor, size);
-        } else if (ref->clazz == NULL) {
+        if (ref == NULL)
+            continue;
+
+        elems = getElementCount(ref);
+
+        if (ref->clazz == NULL) {
             /* should only be possible right after a plain dvmMalloc() */
-            LOGW("%5d: %p cls=(raw) (%d bytes)\n", idx, ref, size);
+            size_t size = dvmObjectSizeInHeap(ref);
+            LOGW("%5d: %p cls=(raw) (%zd bytes)\n", idx, ref, size);
+        } else if (ref->clazz == gDvm.classJavaLangClass) {
+            ClassObject* clazz = (ClassObject*) ref;
+            LOGW("%5d: %p cls=%s '%s'\n", idx, ref, ref->clazz->descriptor,
+                clazz->descriptor);
+        } else if (elems != 0) {
+            LOGW("%5d: %p cls=%s [%zd]\n",
+                idx, ref, ref->clazz->descriptor, elems);
         } else {
-            LOGW("%5d: %p cls=%s (%d bytes)\n", idx, ref,
-                (refs[idx] == NULL) ? "-" : ref->clazz->descriptor, size);
+            LOGW("%5d: %p cls=%s\n", idx, ref, ref->clazz->descriptor);
         }
     }
 
@@ -279,39 +302,33 @@ void dvmDumpReferenceTableContents(Object* const* refs, size_t count,
     assert(count > 0);
 
     /*
-     * Dump uniquified table summary.  While we're at it, generate a
-     * cumulative total amount of referenced memory based on the unique
-     * entries.
+     * Dump uniquified table summary.
      */
     LOGW("%s reference table summary (%d entries):\n", descr, count);
-    size_t equiv, identical, total;
-    total = equiv = identical = 0;
+    size_t equiv, identical;
+    equiv = identical = 0;
     for (idx = 1; idx < count; idx++) {
-        size = dvmObjectSizeInHeap(refs[idx-1]);
+        elems = getElementCount(refs[idx-1]);
 
         if (refs[idx] == refs[idx-1]) {
             /* same reference, added more than once */
             identical++;
         } else if (refs[idx]->clazz == refs[idx-1]->clazz &&
-            dvmObjectSizeInHeap(refs[idx]) == size)
+            getElementCount(refs[idx]) == elems)
         {
-            /* same class / size, different object */
-            total += size;
+            /* same class / element count, different object */
             equiv++;
         } else {
             /* different class */
-            total += size;
-            logObject(refs[idx-1], size, identical, equiv);
+            logObject(refs[idx-1], elems, identical, equiv);
             equiv = identical = 0;
         }
     }
 
     /* handle the last entry (everything above outputs refs[i-1]) */
-    size = dvmObjectSizeInHeap(refs[count-1]);
-    total += size;
-    logObject(refs[count-1], size, identical, equiv);
+    elems = getElementCount(refs[idx-1]);
+    logObject(refs[count-1], elems, identical, equiv);
 
-    LOGW("Memory held directly by tracked refs is %d bytes\n", total);
     free(tableCopy);
 }