LogMessageBuilder operator<<(LogMessageBuilder builder, const TransformFeedback * object) { logObject(builder, object, "TransformFeedback"); return builder; }
LogMessageBuilder operator<<(LogMessageBuilder builder, const VertexArray * object) { logObject(builder, object, "VertexArrayObject"); return builder; }
LogMessageBuilder operator<<(LogMessageBuilder builder, const Shader * object) { logObject(builder, object, "Shader"); return builder; }
LogMessageBuilder operator<<(LogMessageBuilder builder, const Texture * object) { logObject(builder, object, "Texture"); return builder; }
LogMessageBuilder operator<<(LogMessageBuilder builder, const Renderbuffer * object) { logObject(builder, object, "RenderBufferObject"); return builder; }
LogMessageBuilder operator<<(LogMessageBuilder builder, const Query * object) { logObject(builder, object, "Query"); return builder; }
LogMessageBuilder operator<<(LogMessageBuilder builder, const Program * object) { logObject(builder, object, "Program"); return builder; }
LogMessageBuilder operator<<(LogMessageBuilder builder, const Object * object) { logObject(builder, object, "Object"); return builder; }
/* * Dump the contents of a ReferenceTable to the log. * * The caller should lock any external sync before calling. * * (This was originally written to be tolerant of null entries in the table. * I don't think that can happen anymore.) */ void dvmDumpReferenceTable(const ReferenceTable* pRef, const char* descr) { const int kLast = 10; int count = dvmReferenceTableEntries(pRef); Object** refs; int i; if (count == 0) { LOGW("%s reference table has no entries\n", descr); return; } assert(count > 0); /* * Dump the most recent N entries. */ LOGW("Last %d entries in %s reference table:\n", kLast, descr); refs = pRef->table; // use unsorted list int size; int start = count - kLast; if (start < 0) start = 0; for (i = start; i < count; i++) { size = (refs[i] == NULL) ? 0 : dvmObjectSizeInHeap(refs[i]); Object* ref = refs[i]; if (ref->clazz == gDvm.classJavaLangClass) { ClassObject* clazz = (ClassObject*) ref; LOGW("%5d: %p cls=%s '%s' (%d bytes)\n", i, ref, (refs[i] == NULL) ? "-" : ref->clazz->descriptor, clazz->descriptor, size); } else if (ref->clazz == NULL) { /* should only be possible right after a plain dvmMalloc() */ LOGW("%5d: %p cls=(raw) (%d bytes)\n", i, ref, size); } else { LOGW("%5d: %p cls=%s (%d bytes)\n", i, ref, (refs[i] == NULL) ? "-" : ref->clazz->descriptor, size); } } /* * Make a copy of the table, and sort it. */ Object** tableCopy = (Object**)malloc(sizeof(Object*) * count); memcpy(tableCopy, pRef->table, sizeof(Object*) * count); qsort(tableCopy, count, sizeof(Object*), compareObject); refs = tableCopy; // use sorted list /* * Dump uniquified table summary. While we're at it, generate a * cumulative total amount of pinned memory based on the unique entries. */ LOGW("%s reference table summary (%d entries):\n", descr, count); int equiv, identical, total; total = equiv = identical = 0; for (i = 1; i < count; i++) { size = (refs[i-1] == NULL) ? 0 : dvmObjectSizeInHeap(refs[i-1]); if (refs[i] == refs[i-1]) { /* same reference, added more than once */ identical++; } else if (refs[i]->clazz == refs[i-1]->clazz && (int) dvmObjectSizeInHeap(refs[i]) == size) { /* same class / size, different object */ total += size; equiv++; } else { /* different class */ total += size; logObject(refs[i-1], size, identical, equiv); equiv = identical = 0; } } /* handle the last entry (everything above outputs refs[i-1]) */ size = (refs[count-1] == NULL) ? 0 : dvmObjectSizeInHeap(refs[count-1]); total += size; logObject(refs[count-1], size, identical, equiv); LOGW("Memory held directly by tracked refs is %d bytes\n", total); free(tableCopy); }