Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2a293b61 authored by Jeff Brown's avatar Jeff Brown
Browse files

Clean up SQLite debugging code.

Deleted a bunch of dead / useless code.
Raised number of logged operations in dumpsys dbinfo to 20.

Change-Id: I88344ff57a978f200c1f0172141d91e430caa1a9
parent 6534c0e0
Loading
Loading
Loading
Loading
+5 −8
Original line number Diff line number Diff line
@@ -486,7 +486,6 @@ public final class ActivityThread {
        private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s";
        private static final String ONE_COUNT_COLUMN = "%21s %8d";
        private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
        private static final String TWO_COUNT_COLUMNS_DB = "%21s %8d %21s %8d";
        private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";

        // Formatting for checkin service - update version if row format changes
@@ -867,7 +866,6 @@ public final class ActivityThread {
            int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
            int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
            long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class);
            long sqliteAllocated = SQLiteDebug.getHeapAllocatedSize() / 1024;
            SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();

            // For checkin, we print one long comma-separated list of values
@@ -935,9 +933,9 @@ public final class ActivityThread {
                pw.print(openSslSocketCount); pw.print(',');

                // SQL
                pw.print(sqliteAllocated); pw.print(',');
                pw.print(stats.memoryUsed / 1024); pw.print(',');
                pw.print(stats.pageCacheOverflo / 1024); pw.print(',');
                pw.print(stats.memoryUsed / 1024); pw.print(',');
                pw.print(stats.pageCacheOverflow / 1024); pw.print(',');
                pw.print(stats.largestMemAlloc / 1024);
                for (int i = 0; i < stats.dbStats.size(); i++) {
                    DbStats dbStats = stats.dbStats.get(i);
@@ -1003,10 +1001,9 @@ public final class ActivityThread {
            // SQLite mem info
            pw.println(" ");
            pw.println(" SQL");
            printRow(pw, TWO_COUNT_COLUMNS_DB, "heap:", sqliteAllocated, "MEMORY_USED:",
                    stats.memoryUsed / 1024);
            printRow(pw, TWO_COUNT_COLUMNS_DB, "PAGECACHE_OVERFLOW:",
                    stats.pageCacheOverflo / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
            printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024);
            printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:",
                    stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
            pw.println(" ");
            int N = stats.dbStats.size();
            if (N > 0) {
+5 −3
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ import java.util.regex.Pattern;
 */
public final class SQLiteConnection {
    private static final String TAG = "SQLiteConnection";
    private static final boolean DEBUG = false;

    private static final String[] EMPTY_STRING_ARRAY = new String[0];
    private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
@@ -668,11 +669,12 @@ public final class SQLiteConnection {
                // When remove() is called, the cache will invoke its entryRemoved() callback,
                // which will in turn call finalizePreparedStatement() to finalize and
                // recycle the statement.
                if (SQLiteDebug.DEBUG_SQL_CACHE) {
                    Log.v(TAG, "Could not reset prepared statement due to an exception.  "
                if (DEBUG) {
                    Log.d(TAG, "Could not reset prepared statement due to an exception.  "
                            + "Removing it from the cache.  SQL: "
                            + trimSqlForDisplay(statement.mSql), ex);
                }

                mPreparedStatementCache.remove(statement.mSql);
            }
        } else {
@@ -995,7 +997,7 @@ public final class SQLiteConnection {
    }

    private static final class OperationLog {
        private static final int MAX_RECENT_OPERATIONS = 10;
        private static final int MAX_RECENT_OPERATIONS = 20;
        private static final int COOKIE_GENERATION_SHIFT = 8;
        private static final int COOKIE_INDEX_MASK = 0xff;

+0 −1
Original line number Diff line number Diff line
@@ -269,7 +269,6 @@ public class SQLiteCursor extends AbstractWindowedCursor {
                        mStackTrace);
                }
                close();
                SQLiteDebug.notifyActiveCursorFinalized();
            }
        } finally {
            super.finalize();
+1 −86
Original line number Diff line number Diff line
@@ -48,31 +48,6 @@ public final class SQLiteDebug {
    public static final boolean DEBUG_SQL_TIME =
            Log.isLoggable("SQLiteTime", Log.VERBOSE);

    /**
     * Controls the printing of compiled-sql-statement cache stats.
     */
    public static final boolean DEBUG_SQL_CACHE =
            Log.isLoggable("SQLiteCompiledSql", Log.VERBOSE);

    /**
     * Controls the stack trace reporting of active cursors being
     * finalized.
     */
    public static final boolean DEBUG_ACTIVE_CURSOR_FINALIZATION =
            Log.isLoggable("SQLiteCursorClosing", Log.VERBOSE);

    /**
     * Controls the tracking of time spent holding the database lock.
     */
    public static final boolean DEBUG_LOCK_TIME_TRACKING =
            Log.isLoggable("SQLiteLockTime", Log.VERBOSE);

    /**
     * Controls the printing of stack traces when tracking the time spent holding the database lock.
     */
    public static final boolean DEBUG_LOCK_TIME_TRACKING_STACK_TRACE =
            Log.isLoggable("SQLiteLockStackTrace", Log.VERBOSE);

    /**
     * True to enable database performance testing instrumentation.
     * @hide
@@ -101,27 +76,6 @@ public final class SQLiteDebug {
     * @see #getPagerStats(PagerStats)
     */
    public static class PagerStats {
        /** The total number of bytes in all pagers in the current process
         * @deprecated not used any longer
         */
        @Deprecated
        public long totalBytes;
        /** The number of bytes in referenced pages in all pagers in the current process
         * @deprecated not used any longer
         * */
        @Deprecated
        public long referencedBytes;
        /** The number of bytes in all database files opened in the current process
         * @deprecated not used any longer
         */
        @Deprecated
        public long databaseBytes;
        /** The number of pagers opened in the current process
         * @deprecated not used any longer
         */
        @Deprecated
        public int numPagers;

        /** the current amount of memory checked out by sqlite using sqlite3_malloc().
         * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
         */
@@ -134,7 +88,7 @@ public final class SQLiteDebug {
         * that overflowed because no space was left in the page cache.
         * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
         */
        public int pageCacheOverflo;
        public int pageCacheOverflow;

        /** records the largest memory allocation request handed to sqlite3.
         * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
@@ -207,43 +161,4 @@ public final class SQLiteDebug {
     * Gathers statistics about all pagers in the current process.
     */
    public static native void getPagerStats(PagerStats stats);

    /**
     * Returns the size of the SQLite heap.
     * @return The size of the SQLite heap in bytes.
     */
    public static native long getHeapSize();

    /**
     * Returns the amount of allocated memory in the SQLite heap.
     * @return The allocated size in bytes.
     */
    public static native long getHeapAllocatedSize();

    /**
     * Returns the amount of free memory in the SQLite heap.
     * @return The freed size in bytes.
     */
    public static native long getHeapFreeSize();

    /**
     * Determines the number of dirty belonging to the SQLite
     * heap segments of this process.  pages[0] returns the number of
     * shared pages, pages[1] returns the number of private pages
     */
    public static native void getHeapDirtyPages(int[] pages);

    private static int sNumActiveCursorsFinalized = 0;

    /**
     * Returns the number of active cursors that have been finalized. This depends on the GC having
     * run but is still useful for tests.
     */
    public static int getNumActiveCursorsFinalized() {
        return sNumActiveCursorsFinalized;
    }

    static synchronized void notifyActiveCursorFinalized() {
        sNumActiveCursorsFinalized++;
    }
}
+7 −142
Original line number Diff line number Diff line
@@ -26,13 +26,10 @@

#include <sqlite3.h>

// From mem_mspace.c in libsqlite
extern "C" mspace sqlite3_get_mspace();

namespace android {

static jfieldID gMemoryUsedField;
static jfieldID gPageCacheOverfloField;
static jfieldID gPageCacheOverflowField;
static jfieldID gLargestMemAllocField;


@@ -41,146 +38,18 @@ static jfieldID gLargestMemAllocField;
static void getPagerStats(JNIEnv *env, jobject clazz, jobject statsObj)
{
    int memoryUsed;
    int pageCacheOverflo;
    int pageCacheOverflow;
    int largestMemAlloc;
    int unused;

    sqlite3_status(SQLITE_STATUS_MEMORY_USED, &memoryUsed, &unused, 0);
    sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &unused, &largestMemAlloc, 0);
    sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &pageCacheOverflo, &unused, 0);
    sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &pageCacheOverflow, &unused, 0);
    env->SetIntField(statsObj, gMemoryUsedField, memoryUsed);
    env->SetIntField(statsObj, gPageCacheOverfloField, pageCacheOverflo);
    env->SetIntField(statsObj, gPageCacheOverflowField, pageCacheOverflow);
    env->SetIntField(statsObj, gLargestMemAllocField, largestMemAlloc);
}

static jlong getHeapSize(JNIEnv *env, jobject clazz)
{
#if !NO_MALLINFO
    struct mallinfo info = mspace_mallinfo(sqlite3_get_mspace());
    struct mallinfo info = dlmallinfo();
    return (jlong) info.usmblks;
#elif USE_MSPACE
    mspace space = sqlite3_get_mspace();
    if (space != 0) {
        return mspace_footprint(space);
    } else {
        return 0;
    }
#else
    return 0;
#endif
}

static jlong getHeapAllocatedSize(JNIEnv *env, jobject clazz)
{
#if !NO_MALLINFO
    struct mallinfo info = mspace_mallinfo(sqlite3_get_mspace());
    return (jlong) info.uordblks;
#else
    return sqlite3_memory_used();
#endif
}

static jlong getHeapFreeSize(JNIEnv *env, jobject clazz)
{
#if !NO_MALLINFO
    struct mallinfo info = mspace_mallinfo(sqlite3_get_mspace());
    return (jlong) info.fordblks;
#else
    return getHeapSize(env, clazz) - sqlite3_memory_used();
#endif
}

static int read_mapinfo(FILE *fp,
        int *sharedPages, int *privatePages)
{
    char line[1024];
    int len;
    int skip;

    unsigned start = 0, size = 0, resident = 0;
    unsigned shared_clean = 0, shared_dirty = 0;
    unsigned private_clean = 0, private_dirty = 0;
    unsigned referenced = 0;

    int isAnon = 0;
    int isHeap = 0;

again:
    skip = 0;
    
    if(fgets(line, 1024, fp) == 0) return 0;

    len = strlen(line);
    if (len < 1) return 0;
    line[--len] = 0;

    /* ignore guard pages */
    if (line[18] == '-') skip = 1;

    start = strtoul(line, 0, 16);

    if (len > 50 && !strncmp(line + 49, "/tmp/sqlite-heap", strlen("/tmp/sqlite-heap"))) {
        isHeap = 1;
    }

    if (fgets(line, 1024, fp) == 0) return 0;
    if (sscanf(line, "Size: %d kB", &size) != 1) return 0;
    if (fgets(line, 1024, fp) == 0) return 0;
    if (sscanf(line, "Rss: %d kB", &resident) != 1) return 0;
    if (fgets(line, 1024, fp) == 0) return 0;
    if (sscanf(line, "Shared_Clean: %d kB", &shared_clean) != 1) return 0;
    if (fgets(line, 1024, fp) == 0) return 0;
    if (sscanf(line, "Shared_Dirty: %d kB", &shared_dirty) != 1) return 0;
    if (fgets(line, 1024, fp) == 0) return 0;
    if (sscanf(line, "Private_Clean: %d kB", &private_clean) != 1) return 0;
    if (fgets(line, 1024, fp) == 0) return 0;
    if (sscanf(line, "Private_Dirty: %d kB", &private_dirty) != 1) return 0;
    if (fgets(line, 1024, fp) == 0) return 0;
    if (sscanf(line, "Referenced: %d kB", &referenced) != 1) return 0;
    
    if (skip) {
        goto again;
    }

    if (isHeap) {
        *sharedPages += shared_dirty;
        *privatePages += private_dirty;
    }
    return 1;
}

static void load_maps(int pid, int *sharedPages, int *privatePages)
{
    char tmp[128];
    FILE *fp;
    
    sprintf(tmp, "/proc/%d/smaps", pid);
    fp = fopen(tmp, "r");
    if (fp == 0) return;
    
    while (read_mapinfo(fp, sharedPages, privatePages) != 0) {
        // Do nothing
    }
    fclose(fp);
}

static void getHeapDirtyPages(JNIEnv *env, jobject clazz, jintArray pages)
{
    int _pages[2];

    _pages[0] = 0;
    _pages[1] = 0;

    load_maps(getpid(), &_pages[0], &_pages[1]);

    // Convert from kbytes to 4K pages
    _pages[0] /= 4;
    _pages[1] /= 4;

    env->SetIntArrayRegion(pages, 0, 2, _pages);
}

/*
 * JNI registration.
 */
@@ -189,10 +58,6 @@ static JNINativeMethod gMethods[] =
{
    { "getPagerStats", "(Landroid/database/sqlite/SQLiteDebug$PagerStats;)V",
            (void*) getPagerStats },
    { "getHeapSize", "()J", (void*) getHeapSize },
    { "getHeapAllocatedSize", "()J", (void*) getHeapAllocatedSize },
    { "getHeapFreeSize", "()J", (void*) getHeapFreeSize },
    { "getHeapDirtyPages", "([I)V", (void*) getHeapDirtyPages },
};

int register_android_database_SQLiteDebug(JNIEnv *env)
@@ -217,9 +82,9 @@ int register_android_database_SQLiteDebug(JNIEnv *env)
        return -1;
    }

    gPageCacheOverfloField = env->GetFieldID(clazz, "pageCacheOverflo", "I");
    if (gPageCacheOverfloField == NULL) {
        ALOGE("Can't find pageCacheOverflo");
    gPageCacheOverflowField = env->GetFieldID(clazz, "pageCacheOverflow", "I");
    if (gPageCacheOverflowField == NULL) {
        ALOGE("Can't find pageCacheOverflow");
        return -1;
    }