android_os_Debug.cpp revision 3025ef332c29e255388f74b2afefe05f64bce07c
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h"
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h"
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/misc.h"
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <time.h>
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/time.h>
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <malloc.h>
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID dalvikPss_field;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID dalvikPrivateDirty_field;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID dalvikSharedDirty_field;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID nativePss_field;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID nativePrivateDirty_field;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID nativeSharedDirty_field;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID otherPss_field;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID otherPrivateDirty_field;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID otherSharedDirty_field;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct stats_t {
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int dalvikPss;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int dalvikPrivateDirty;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int dalvikSharedDirty;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int nativePss;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int nativePrivateDirty;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int nativeSharedDirty;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int otherPss;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int otherPrivateDirty;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int otherSharedDirty;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define BINDER_STATS "/proc/binder/stats"
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapSize(JNIEnv *env, jobject clazz)
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    struct mallinfo info = mallinfo();
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (jlong) info.usmblks;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapAllocatedSize(JNIEnv *env, jobject clazz)
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    struct mallinfo info = mallinfo();
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (jlong) info.uordblks;
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapFreeSize(JNIEnv *env, jobject clazz)
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    struct mallinfo info = mallinfo();
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (jlong) info.fordblks;
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void read_mapinfo(FILE *fp, stats_t* stats)
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char line[1024];
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int len;
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool skip, done = false;
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    unsigned start = 0, size = 0, resident = 0, pss = 0;
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    unsigned shared_clean = 0, shared_dirty = 0;
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    unsigned private_clean = 0, private_dirty = 0;
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    unsigned referenced = 0;
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    unsigned temp;
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int isNativeHeap;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int isDalvikHeap;
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int isSqliteHeap;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if(fgets(line, 1024, fp) == 0) return;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (!done) {
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        isNativeHeap = 0;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        isDalvikHeap = 0;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        isSqliteHeap = 0;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        skip = false;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        len = strlen(line);
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (len < 1) return;
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        line[--len] = 0;
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* ignore guard pages */
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (len > 18 && line[17] == '-') skip = true;
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        start = strtoul(line, 0, 16);
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (strstr(line, "[heap]")) {
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            isNativeHeap = 1;
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (strstr(line, "/dalvik-LinearAlloc")) {
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            isDalvikHeap = 1;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (strstr(line, "/mspace/dalvik-heap")) {
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            isDalvikHeap = 1;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (strstr(line, "/dalvik-heap-bitmap/")) {
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            isDalvikHeap = 1;
132bd51116a5310683f70a37110bf735252dc7e4e38Grace Kloba        } else if (strstr(line, "/data/dalvik-cache/")) {
133bd51116a5310683f70a37110bf735252dc7e4e38Grace Kloba            isDalvikHeap = 1;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (strstr(line, "/tmp/sqlite-heap")) {
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            isSqliteHeap = 1;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //LOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap,
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //    isSqliteHeap, line);
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (true) {
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (fgets(line, 1024, fp) == 0) {
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                done = true;
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (sscanf(line, "Size: %d kB", &temp) == 1) {
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                size = temp;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (sscanf(line, "Rss: %d kB", &temp) == 1) {
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resident = temp;
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (sscanf(line, "Pss: %d kB", &temp) == 1) {
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pss = temp;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (sscanf(line, "Shared_Clean: %d kB", &temp) == 1) {
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                shared_clean = temp;
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (sscanf(line, "Shared_Dirty: %d kB", &temp) == 1) {
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                shared_dirty = temp;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (sscanf(line, "Private_Clean: %d kB", &temp) == 1) {
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                private_clean = temp;
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (sscanf(line, "Private_Dirty: %d kB", &temp) == 1) {
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                private_dirty = temp;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (sscanf(line, "Referenced: %d kB", &temp) == 1) {
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                referenced = temp;
163bd51116a5310683f70a37110bf735252dc7e4e38Grace Kloba            } else if (strlen(line) > 30 && line[8] == '-' && line[17] == ' ') {
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // looks like a new mapping
165bd51116a5310683f70a37110bf735252dc7e4e38Grace Kloba                // example: "10000000-10001000 ---p 10000000 00:00 0"
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!skip) {
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (isNativeHeap) {
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                stats->nativePss += pss;
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                stats->nativePrivateDirty += private_dirty;
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                stats->nativeSharedDirty += shared_dirty;
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (isDalvikHeap) {
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                stats->dalvikPss += pss;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                stats->dalvikPrivateDirty += private_dirty;
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                stats->dalvikSharedDirty += shared_dirty;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if ( isSqliteHeap) {
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // ignore
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                stats->otherPss += pss;
183bd51116a5310683f70a37110bf735252dc7e4e38Grace Kloba                stats->otherPrivateDirty += private_dirty;
184bd51116a5310683f70a37110bf735252dc7e4e38Grace Kloba                stats->otherSharedDirty += shared_dirty;
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void load_maps(int pid, stats_t* stats)
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char tmp[128];
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FILE *fp;
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sprintf(tmp, "/proc/%d/smaps", pid);
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fp = fopen(tmp, "r");
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fp == 0) return;
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    read_mapinfo(fp, stats);
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fclose(fp);
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2033025ef332c29e255388f74b2afefe05f64bce07cDianne Hackbornstatic void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
2043025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn        jint pid, jobject object)
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    stats_t stats;
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memset(&stats, 0, sizeof(stats_t));
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2093025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn    load_maps(pid, &stats);
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(object, dalvikPss_field, stats.dalvikPss);
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(object, dalvikPrivateDirty_field, stats.dalvikPrivateDirty);
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(object, dalvikSharedDirty_field, stats.dalvikSharedDirty);
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(object, nativePss_field, stats.nativePss);
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(object, nativePrivateDirty_field, stats.nativePrivateDirty);
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(object, nativeSharedDirty_field, stats.nativeSharedDirty);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(object, otherPss_field, stats.otherPss);
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(object, otherPrivateDirty_field, stats.otherPrivateDirty);
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(object, otherSharedDirty_field, stats.otherSharedDirty);
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2243025ef332c29e255388f74b2afefe05f64bce07cDianne Hackbornstatic void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object)
2253025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn{
2263025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn    android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object);
2273025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn}
2283025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint read_binder_stat(const char* stat)
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FILE* fp = fopen(BINDER_STATS, "r");
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fp == NULL) {
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char line[1024];
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char compare[128];
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int len = snprintf(compare, 128, "proc %d", getpid());
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // loop until we have the block that represents this process
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    do {
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (fgets(line, 1024, fp) == 0) {
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return -1;
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } while (strncmp(compare, line, len));
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // now that we have this process, read until we find the stat that we are looking for
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    len = snprintf(compare, 128, "  %s: ", stat);
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    do {
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (fgets(line, 1024, fp) == 0) {
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return -1;
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } while (strncmp(compare, line, len));
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // we have the line, now increment the line ptr to the value
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* ptr = line + len;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return atoi(ptr);
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_Debug_getBinderSentTransactions(JNIEnv *env, jobject clazz)
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return read_binder_stat("bcTRANSACTION");
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_getBinderReceivedTransactions(JNIEnv *env, jobject clazz)
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return read_binder_stat("brTRANSACTION");
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// these are implemented in android_util_Binder.cpp
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz);
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz);
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz);
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * JNI registration.
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMethods[] = {
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getNativeHeapSize",      "()J",
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*) android_os_Debug_getNativeHeapSize },
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getNativeHeapAllocatedSize", "()J",
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*) android_os_Debug_getNativeHeapAllocatedSize },
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getNativeHeapFreeSize",  "()J",
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*) android_os_Debug_getNativeHeapFreeSize },
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getMemoryInfo",          "(Landroid/os/Debug$MemoryInfo;)V",
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*) android_os_Debug_getDirtyPages },
2903025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn    { "getMemoryInfo",          "(ILandroid/os/Debug$MemoryInfo;)V",
2913025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn            (void*) android_os_Debug_getDirtyPagesPid },
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getBinderSentTransactions", "()I",
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*) android_os_Debug_getBinderSentTransactions },
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getBinderReceivedTransactions", "()I",
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*) android_os_getBinderReceivedTransactions },
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getBinderLocalObjectCount", "()I",
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*)android_os_Debug_getLocalObjectCount },
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getBinderProxyObjectCount", "()I",
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*)android_os_Debug_getProxyObjectCount },
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getBinderDeathObjectCount", "()I",
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*)android_os_Debug_getDeathObjectCount },
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_os_Debug(JNIEnv *env)
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass clazz = env->FindClass("android/os/Debug$MemoryInfo");
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dalvikPss_field = env->GetFieldID(clazz, "dalvikPss", "I");
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dalvikPrivateDirty_field = env->GetFieldID(clazz, "dalvikPrivateDirty", "I");
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dalvikSharedDirty_field = env->GetFieldID(clazz, "dalvikSharedDirty", "I");
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nativePss_field = env->GetFieldID(clazz, "nativePss", "I");
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nativePrivateDirty_field = env->GetFieldID(clazz, "nativePrivateDirty", "I");
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nativeSharedDirty_field = env->GetFieldID(clazz, "nativeSharedDirty", "I");
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    otherPss_field = env->GetFieldID(clazz, "otherPss", "I");
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    otherPrivateDirty_field = env->GetFieldID(clazz, "otherPrivateDirty", "I");
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    otherSharedDirty_field = env->GetFieldID(clazz, "otherSharedDirty", "I");
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods));
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
324