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
1706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#define LOG_TAG "android.os.Debug"
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h"
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h"
20f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn#include <utils/String8.h>
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/misc.h"
22f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn#include "cutils/debugger.h"
235b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski#include <memtrack/memtrack.h>
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2587eac99a21772ae56018cb81db6966557b459554Ruben Brunk#include <cutils/log.h>
26f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn#include <fcntl.h>
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h>
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <time.h>
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/time.h>
3306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#include <errno.h>
3406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#include <assert.h>
350e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn#include <ctype.h>
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <malloc.h>
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
440e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornenum {
450e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    HEAP_UNKNOWN,
460e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    HEAP_DALVIK,
470e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    HEAP_NATIVE,
4864770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn    HEAP_DALVIK_OTHER,
497c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers    HEAP_STACK,
500e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    HEAP_CURSOR,
510e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    HEAP_ASHMEM,
520e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    HEAP_UNKNOWN_DEV,
530e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    HEAP_SO,
540e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    HEAP_JAR,
550e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    HEAP_APK,
560e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    HEAP_TTF,
570e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    HEAP_DEX,
588884ef4fe80505bc6e41c167b67efbb93e43475dAnwar Ghuloum    HEAP_OAT,
5988887d0a53f866e61a7524b0edfc95e6dde57d72Anwar Ghuloum    HEAP_ART,
600e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    HEAP_UNKNOWN_MAP,
615b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    HEAP_GRAPHICS,
625b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    HEAP_GL,
635b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    HEAP_OTHER_MEMTRACK,
6464770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn
653c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    HEAP_DALVIK_NORMAL,
663c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    HEAP_DALVIK_LARGE,
673c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    HEAP_DALVIK_LINEARALLOC,
683c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    HEAP_DALVIK_ACCOUNTING,
693c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    HEAP_DALVIK_CODE_CACHE,
700e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn
710e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    _NUM_HEAP,
725b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    _NUM_EXCLUSIVE_HEAP = HEAP_OTHER_MEMTRACK+1,
730e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    _NUM_CORE_HEAP = HEAP_NATIVE+1
740e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn};
750e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn
760e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstruct stat_fields {
770e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    jfieldID pss_field;
783c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    jfieldID pssSwappable_field;
790e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    jfieldID privateDirty_field;
800e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    jfieldID sharedDirty_field;
813c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    jfieldID privateClean_field;
823a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum    jfieldID sharedClean_field;
838883ced18ac25199330843964634fdf70647a127Dianne Hackborn    jfieldID swappedOut_field;
840e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn};
850e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn
860e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstruct stat_field_names {
870e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    const char* pss_name;
883c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    const char* pssSwappable_name;
890e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    const char* privateDirty_name;
900e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    const char* sharedDirty_name;
913c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    const char* privateClean_name;
923a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum    const char* sharedClean_name;
938883ced18ac25199330843964634fdf70647a127Dianne Hackborn    const char* swappedOut_name;
940e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn};
950e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn
960e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstatic stat_fields stat_fields[_NUM_CORE_HEAP];
970e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn
980e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstatic stat_field_names stat_field_names[_NUM_CORE_HEAP] = {
998883ced18ac25199330843964634fdf70647a127Dianne Hackborn    { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty",
1008883ced18ac25199330843964634fdf70647a127Dianne Hackborn        "otherPrivateClean", "otherSharedClean", "otherSwappedOut" },
1018883ced18ac25199330843964634fdf70647a127Dianne Hackborn    { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty",
1028883ced18ac25199330843964634fdf70647a127Dianne Hackborn        "dalvikPrivateClean", "dalvikSharedClean", "dalvikSwappedOut" },
1038883ced18ac25199330843964634fdf70647a127Dianne Hackborn    { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty",
1048883ced18ac25199330843964634fdf70647a127Dianne Hackborn        "nativePrivateClean", "nativeSharedClean", "nativeSwappedOut" }
1050e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn};
1060e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn
1070e3328fbdd3845b0e2bec364e951498eaee6b079Dianne HackbornjfieldID otherStats_field;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1095b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinskistatic bool memtrackLoaded;
1105b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct stats_t {
1120e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    int pss;
1133c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    int swappablePss;
1140e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    int privateDirty;
1150e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    int sharedDirty;
1163c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    int privateClean;
1173a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum    int sharedClean;
1188883ced18ac25199330843964634fdf70647a127Dianne Hackborn    int swappedOut;
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define BINDER_STATS "/proc/binder/stats"
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapSize(JNIEnv *env, jobject clazz)
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    struct mallinfo info = mallinfo();
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (jlong) info.usmblks;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapAllocatedSize(JNIEnv *env, jobject clazz)
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    struct mallinfo info = mallinfo();
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (jlong) info.uordblks;
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapFreeSize(JNIEnv *env, jobject clazz)
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1457c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers#ifdef HAVE_MALLOC_H
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    struct mallinfo info = mallinfo();
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return (jlong) info.fordblks;
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -1;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1535b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski// Container used to retrieve graphics memory pss
1545b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinskistruct graphics_memory_pss
15537c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn{
1565b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    int graphics;
1575b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    int gl;
1585b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    int other;
1595b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski};
16037c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn
1615b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski/*
1625b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski * Uses libmemtrack to retrieve graphics memory that the process is using.
1635b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski * Any graphics memory reported in /proc/pid/smaps is not included here.
1645b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski */
165cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackbornstatic int read_memtrack_memory(struct memtrack_proc* p, int pid,
166cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn        struct graphics_memory_pss* graphics_mem)
1675b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski{
1685b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    int err = memtrack_proc_get(p, pid);
1695b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    if (err != 0) {
170cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn        ALOGW("failed to get memory consumption info: %d", err);
1715b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        return err;
17237c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn    }
17337c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn
1745b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    ssize_t pss = memtrack_proc_graphics_pss(p);
1755b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    if (pss < 0) {
176cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn        ALOGW("failed to get graphics pss: %d", pss);
1775b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        return pss;
1785b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    }
1795b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    graphics_mem->graphics = pss / 1024;
18037c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn
1815b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    pss = memtrack_proc_gl_pss(p);
1825b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    if (pss < 0) {
183cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn        ALOGW("failed to get gl pss: %d", pss);
1845b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        return pss;
1855b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    }
1865b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    graphics_mem->gl = pss / 1024;
18737c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn
1885b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    pss = memtrack_proc_other_pss(p);
1895b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    if (pss < 0) {
190cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn        ALOGW("failed to get other pss: %d", pss);
1915b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        return pss;
1925b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    }
1935b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    graphics_mem->other = pss / 1024;
19437c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn
1955b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    return 0;
1965b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski}
19737c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn
1985b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski/*
1995b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski * Retrieves the graphics memory that is unaccounted for in /proc/pid/smaps.
2005b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski */
2015b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinskistatic int read_memtrack_memory(int pid, struct graphics_memory_pss* graphics_mem)
2025b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski{
2035b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    if (!memtrackLoaded) {
2045b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        return -1;
20537c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn    }
20637c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn
2075b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    struct memtrack_proc* p = memtrack_proc_new();
2085b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    if (p == NULL) {
209cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn        ALOGW("failed to create memtrack_proc");
2105b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        return -1;
2115b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    }
21237c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn
2135b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    int err = read_memtrack_memory(p, pid, graphics_mem);
2145b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    memtrack_proc_destroy(p);
2155b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    return err;
21637c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn}
21737c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void read_mapinfo(FILE *fp, stats_t* stats)
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char line[1024];
2210e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    int len, nameLen;
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool skip, done = false;
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2243c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    unsigned size = 0, resident = 0, pss = 0, swappable_pss = 0;
2253c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    float sharing_proportion = 0.0;
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    unsigned shared_clean = 0, shared_dirty = 0;
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    unsigned private_clean = 0, private_dirty = 0;
2288883ced18ac25199330843964634fdf70647a127Dianne Hackborn    unsigned swapped_out = 0;
2293c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    bool is_swappable = false;
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    unsigned referenced = 0;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    unsigned temp;
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2330e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    unsigned long int start;
2340e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    unsigned long int end = 0;
2350e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    unsigned long int prevEnd = 0;
2360e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    char* name;
2370e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    int name_pos;
2380e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn
2390e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    int whichHeap = HEAP_UNKNOWN;
2403c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    int subHeap = HEAP_UNKNOWN;
2410e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    int prevHeap = HEAP_UNKNOWN;
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2430e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    if(fgets(line, sizeof(line), fp) == 0) return;
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (!done) {
2460e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        prevHeap = whichHeap;
2470e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        prevEnd = end;
2480e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        whichHeap = HEAP_UNKNOWN;
2493c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum        subHeap = HEAP_UNKNOWN;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        skip = false;
2513c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum        is_swappable = false;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        len = strlen(line);
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (len < 1) return;
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        line[--len] = 0;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2570e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        if (sscanf(line, "%lx-%lx %*s %*x %*x:%*x %*d%n", &start, &end, &name_pos) != 2) {
2580e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn            skip = true;
2590e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        } else {
2600e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn            while (isspace(line[name_pos])) {
2610e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn                name_pos += 1;
2620e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn            }
2630e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn            name = line + name_pos;
2640e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn            nameLen = strlen(name);
2650e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn
26664770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn            if ((strstr(name, "[heap]") == name)) {
2670e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn                whichHeap = HEAP_NATIVE;
26864770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn            } else if (strncmp(name, "/dev/ashmem", 11) == 0) {
26964770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                if (strncmp(name, "/dev/ashmem/dalvik-", 19) == 0) {
27064770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                    whichHeap = HEAP_DALVIK_OTHER;
27164770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                    if (strstr(name, "/dev/ashmem/dalvik-LinearAlloc") == name) {
27264770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                        subHeap = HEAP_DALVIK_LINEARALLOC;
27364770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                    } else if ((strstr(name, "/dev/ashmem/dalvik-mark") == name) ||
27464770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                               (strstr(name, "/dev/ashmem/dalvik-allocspace alloc space live-bitmap") == name) ||
27564770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                               (strstr(name, "/dev/ashmem/dalvik-allocspace alloc space mark-bitmap") == name) ||
27664770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                               (strstr(name, "/dev/ashmem/dalvik-card table") == name) ||
27764770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                               (strstr(name, "/dev/ashmem/dalvik-allocation stack") == name) ||
27864770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                               (strstr(name, "/dev/ashmem/dalvik-live stack") == name) ||
27964770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                               (strstr(name, "/dev/ashmem/dalvik-imagespace") == name) ||
28064770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                               (strstr(name, "/dev/ashmem/dalvik-bitmap") == name) ||
28164770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                               (strstr(name, "/dev/ashmem/dalvik-card-table") == name) ||
28264770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                               (strstr(name, "/dev/ashmem/dalvik-mark-stack") == name) ||
28364770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                               (strstr(name, "/dev/ashmem/dalvik-aux-structure") == name)) {
28464770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                        subHeap = HEAP_DALVIK_ACCOUNTING;
28564770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                    } else if (strstr(name, "/dev/ashmem/dalvik-large") == name) {
28664770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                        whichHeap = HEAP_DALVIK;
28764770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                        subHeap = HEAP_DALVIK_LARGE;
28864770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                    } else if (strstr(name, "/dev/ashmem/dalvik-jit-code-cache") == name) {
28964770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                        subHeap = HEAP_DALVIK_CODE_CACHE;
29064770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                    } else {
29164770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                        // This is the regular Dalvik heap.
29264770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                        whichHeap = HEAP_DALVIK;
29364770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                        subHeap = HEAP_DALVIK_NORMAL;
29464770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                    }
29564770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                } else if (strncmp(name, "/dev/ashmem/CursorWindow", 24) == 0) {
29664770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                    whichHeap = HEAP_CURSOR;
29764770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                } else if (strncmp(name, "/dev/ashmem/libc malloc", 23) == 0) {
29864770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                    whichHeap = HEAP_NATIVE;
29964770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                } else {
30064770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                    whichHeap = HEAP_ASHMEM;
30164770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn                }
302cb4728f247e3793e7fc1baa031290aa732bb77a7Colin Cross            } else if (strncmp(name, "[anon:libc_malloc]", 18) == 0) {
303cb4728f247e3793e7fc1baa031290aa732bb77a7Colin Cross                whichHeap = HEAP_NATIVE;
30464770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn            } else if (strncmp(name, "[stack", 6) == 0) {
3057c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers                whichHeap = HEAP_STACK;
30664770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn            } else if (strncmp(name, "/dev/", 5) == 0) {
3070e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn                whichHeap = HEAP_UNKNOWN_DEV;
3080e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn            } else if (nameLen > 3 && strcmp(name+nameLen-3, ".so") == 0) {
3090e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn                whichHeap = HEAP_SO;
3103c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                is_swappable = true;
3110e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn            } else if (nameLen > 4 && strcmp(name+nameLen-4, ".jar") == 0) {
3120e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn                whichHeap = HEAP_JAR;
3133c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                is_swappable = true;
3140e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn            } else if (nameLen > 4 && strcmp(name+nameLen-4, ".apk") == 0) {
3150e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn                whichHeap = HEAP_APK;
3163c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                is_swappable = true;
3170e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn            } else if (nameLen > 4 && strcmp(name+nameLen-4, ".ttf") == 0) {
3180e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn                whichHeap = HEAP_TTF;
3193c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                is_swappable = true;
3209f8589c31f8910a9c3c33a81675822da9f0cf2dfIan Rogers            } else if ((nameLen > 4 && strcmp(name+nameLen-4, ".dex") == 0) ||
3219f8589c31f8910a9c3c33a81675822da9f0cf2dfIan Rogers                       (nameLen > 5 && strcmp(name+nameLen-5, ".odex") == 0)) {
3220e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn                whichHeap = HEAP_DEX;
3233c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                is_swappable = true;
3248884ef4fe80505bc6e41c167b67efbb93e43475dAnwar Ghuloum            } else if (nameLen > 4 && strcmp(name+nameLen-4, ".oat") == 0) {
3258884ef4fe80505bc6e41c167b67efbb93e43475dAnwar Ghuloum                whichHeap = HEAP_OAT;
3263c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                is_swappable = true;
32788887d0a53f866e61a7524b0edfc95e6dde57d72Anwar Ghuloum            } else if (nameLen > 4 && strcmp(name+nameLen-4, ".art") == 0) {
32888887d0a53f866e61a7524b0edfc95e6dde57d72Anwar Ghuloum                whichHeap = HEAP_ART;
3293c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                is_swappable = true;
330cb4728f247e3793e7fc1baa031290aa732bb77a7Colin Cross            } else if (strncmp(name, "[anon:", 6) == 0) {
331cb4728f247e3793e7fc1baa031290aa732bb77a7Colin Cross                whichHeap = HEAP_UNKNOWN;
3320e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn            } else if (nameLen > 0) {
3330e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn                whichHeap = HEAP_UNKNOWN_MAP;
3340e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn            } else if (start == prevEnd && prevHeap == HEAP_SO) {
3350e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn                // bss section of a shared library.
3360e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn                whichHeap = HEAP_SO;
3370e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn            }
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3406215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        //ALOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap,
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //    isSqliteHeap, line);
3427c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers
3438883ced18ac25199330843964634fdf70647a127Dianne Hackborn        shared_clean = 0;
3448883ced18ac25199330843964634fdf70647a127Dianne Hackborn        shared_dirty = 0;
3458883ced18ac25199330843964634fdf70647a127Dianne Hackborn        private_clean = 0;
3468883ced18ac25199330843964634fdf70647a127Dianne Hackborn        private_dirty = 0;
3478883ced18ac25199330843964634fdf70647a127Dianne Hackborn        swapped_out = 0;
3488883ced18ac25199330843964634fdf70647a127Dianne Hackborn
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (true) {
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (fgets(line, 1024, fp) == 0) {
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                done = true;
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3558883ced18ac25199330843964634fdf70647a127Dianne Hackborn            if (line[0] == 'S' && sscanf(line, "Size: %d kB", &temp) == 1) {
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                size = temp;
3578883ced18ac25199330843964634fdf70647a127Dianne Hackborn            } else if (line[0] == 'R' && sscanf(line, "Rss: %d kB", &temp) == 1) {
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resident = temp;
3598883ced18ac25199330843964634fdf70647a127Dianne Hackborn            } else if (line[0] == 'P' && sscanf(line, "Pss: %d kB", &temp) == 1) {
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pss = temp;
3618883ced18ac25199330843964634fdf70647a127Dianne Hackborn            } else if (line[0] == 'S' && sscanf(line, "Shared_Clean: %d kB", &temp) == 1) {
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                shared_clean = temp;
3638883ced18ac25199330843964634fdf70647a127Dianne Hackborn            } else if (line[0] == 'S' && sscanf(line, "Shared_Dirty: %d kB", &temp) == 1) {
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                shared_dirty = temp;
3658883ced18ac25199330843964634fdf70647a127Dianne Hackborn            } else if (line[0] == 'P' && sscanf(line, "Private_Clean: %d kB", &temp) == 1) {
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                private_clean = temp;
3678883ced18ac25199330843964634fdf70647a127Dianne Hackborn            } else if (line[0] == 'P' && sscanf(line, "Private_Dirty: %d kB", &temp) == 1) {
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                private_dirty = temp;
3698883ced18ac25199330843964634fdf70647a127Dianne Hackborn            } else if (line[0] == 'R' && sscanf(line, "Referenced: %d kB", &temp) == 1) {
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                referenced = temp;
3718883ced18ac25199330843964634fdf70647a127Dianne Hackborn            } else if (line[0] == 'S' && sscanf(line, "Swap: %d kB", &temp) == 1) {
3728883ced18ac25199330843964634fdf70647a127Dianne Hackborn                swapped_out = temp;
373bd51116a5310683f70a37110bf735252dc7e4e38Grace Kloba            } else if (strlen(line) > 30 && line[8] == '-' && line[17] == ' ') {
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // looks like a new mapping
375bd51116a5310683f70a37110bf735252dc7e4e38Grace Kloba                // example: "10000000-10001000 ---p 10000000 00:00 0"
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!skip) {
3813c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum            if (is_swappable && (pss > 0)) {
3823c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                sharing_proportion = 0.0;
3833c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                if ((shared_clean > 0) || (shared_dirty > 0)) {
3848883ced18ac25199330843964634fdf70647a127Dianne Hackborn                    sharing_proportion = (pss - private_clean
3858883ced18ac25199330843964634fdf70647a127Dianne Hackborn                            - private_dirty)/(shared_clean+shared_dirty);
3863c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                }
3873c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                swappable_pss = (sharing_proportion*shared_clean) + private_clean;
3883c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum            } else
3893c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                swappable_pss = 0;
3903c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum
3910e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn            stats[whichHeap].pss += pss;
3923c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum            stats[whichHeap].swappablePss += swappable_pss;
3930e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn            stats[whichHeap].privateDirty += private_dirty;
3940e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn            stats[whichHeap].sharedDirty += shared_dirty;
3953c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum            stats[whichHeap].privateClean += private_clean;
3963a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum            stats[whichHeap].sharedClean += shared_clean;
3978883ced18ac25199330843964634fdf70647a127Dianne Hackborn            stats[whichHeap].swappedOut += swapped_out;
39864770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn            if (whichHeap == HEAP_DALVIK || whichHeap == HEAP_DALVIK_OTHER) {
3993c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                stats[subHeap].pss += pss;
4003c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                stats[subHeap].swappablePss += swappable_pss;
4013c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                stats[subHeap].privateDirty += private_dirty;
4023c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                stats[subHeap].sharedDirty += shared_dirty;
4033c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                stats[subHeap].privateClean += private_clean;
4043c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                stats[subHeap].sharedClean += shared_clean;
4058883ced18ac25199330843964634fdf70647a127Dianne Hackborn                stats[subHeap].swappedOut += swapped_out;
4063c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum            }
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void load_maps(int pid, stats_t* stats)
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char tmp[128];
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FILE *fp;
4157c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sprintf(tmp, "/proc/%d/smaps", pid);
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fp = fopen(tmp, "r");
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fp == 0) return;
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    read_mapinfo(fp, stats);
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fclose(fp);
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4243025ef332c29e255388f74b2afefe05f64bce07cDianne Hackbornstatic void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
4253025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn        jint pid, jobject object)
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4270e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    stats_t stats[_NUM_HEAP];
4280e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    memset(&stats, 0, sizeof(stats));
4297c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers
4300e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    load_maps(pid, stats);
4310e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn
4325b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    struct graphics_memory_pss graphics_mem;
4335b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    if (read_memtrack_memory(pid, &graphics_mem) == 0) {
4345b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        stats[HEAP_GRAPHICS].pss = graphics_mem.graphics;
4355b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        stats[HEAP_GRAPHICS].privateDirty = graphics_mem.graphics;
4365b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        stats[HEAP_GL].pss = graphics_mem.gl;
4375b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        stats[HEAP_GL].privateDirty = graphics_mem.gl;
4385b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        stats[HEAP_OTHER_MEMTRACK].pss = graphics_mem.other;
4395b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        stats[HEAP_OTHER_MEMTRACK].privateDirty = graphics_mem.other;
4405b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    }
44137c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn
4423c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    for (int i=_NUM_CORE_HEAP; i<_NUM_EXCLUSIVE_HEAP; i++) {
4430e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        stats[HEAP_UNKNOWN].pss += stats[i].pss;
4443c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum        stats[HEAP_UNKNOWN].swappablePss += stats[i].swappablePss;
4450e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        stats[HEAP_UNKNOWN].privateDirty += stats[i].privateDirty;
4460e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty;
4473c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum        stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean;
4483a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum        stats[HEAP_UNKNOWN].sharedClean += stats[i].sharedClean;
4498883ced18ac25199330843964634fdf70647a127Dianne Hackborn        stats[HEAP_UNKNOWN].swappedOut += stats[i].swappedOut;
4500e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    }
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4520e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    for (int i=0; i<_NUM_CORE_HEAP; i++) {
4530e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        env->SetIntField(object, stat_fields[i].pss_field, stats[i].pss);
4543c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum        env->SetIntField(object, stat_fields[i].pssSwappable_field, stats[i].swappablePss);
4550e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty);
4560e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty);
4573c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum        env->SetIntField(object, stat_fields[i].privateClean_field, stats[i].privateClean);
4583a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum        env->SetIntField(object, stat_fields[i].sharedClean_field, stats[i].sharedClean);
4598883ced18ac25199330843964634fdf70647a127Dianne Hackborn        env->SetIntField(object, stat_fields[i].swappedOut_field, stats[i].swappedOut);
4600e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    }
4617c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers
4623c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum
4630e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    jintArray otherIntArray = (jintArray)env->GetObjectField(object, otherStats_field);
4647c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers
4650e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0);
4660e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    if (otherArray == NULL) {
4670e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        return;
4680e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    }
4690e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn
4700e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    int j=0;
4710e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) {
4720e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        otherArray[j++] = stats[i].pss;
4733c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum        otherArray[j++] = stats[i].swappablePss;
4740e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        otherArray[j++] = stats[i].privateDirty;
4750e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        otherArray[j++] = stats[i].sharedDirty;
4763c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum        otherArray[j++] = stats[i].privateClean;
4773a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum        otherArray[j++] = stats[i].sharedClean;
4788883ced18ac25199330843964634fdf70647a127Dianne Hackborn        otherArray[j++] = stats[i].swappedOut;
4790e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    }
4800e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn
4810e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0);
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4843025ef332c29e255388f74b2afefe05f64bce07cDianne Hackbornstatic void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object)
4853025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn{
4863025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn    android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object);
4873025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn}
4883025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn
489c8230519728b14065effd3b7d4eca273ff86160cDianne Hackbornstatic jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, jlongArray outUss)
490b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn{
491b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn    char line[1024];
492b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn    jlong pss = 0;
493c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn    jlong uss = 0;
494b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn    unsigned temp;
495b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn
496b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn    char tmp[128];
497b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn    FILE *fp;
498b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn
4995b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    struct graphics_memory_pss graphics_mem;
5005b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    if (read_memtrack_memory(pid, &graphics_mem) == 0) {
5015b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        pss = uss = graphics_mem.graphics + graphics_mem.gl + graphics_mem.other;
5025b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    }
50337c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn
504b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn    sprintf(tmp, "/proc/%d/smaps", pid);
505b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn    fp = fopen(tmp, "r");
506b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn
50737c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn    if (fp != 0) {
50837c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn        while (true) {
50937c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn            if (fgets(line, 1024, fp) == NULL) {
51037c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn                break;
51137c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn            }
512b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn
51337c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn            if (line[0] == 'P') {
51437c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn                if (strncmp(line, "Pss:", 4) == 0) {
51537c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn                    char* c = line + 4;
51637c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn                    while (*c != 0 && (*c < '0' || *c > '9')) {
51737c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn                        c++;
51837c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn                    }
51937c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn                    pss += atoi(c);
52037c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn                } else if (strncmp(line, "Private_Clean:", 14)
52137c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn                        || strncmp(line, "Private_Dirty:", 14)) {
52237c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn                    char* c = line + 14;
52337c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn                    while (*c != 0 && (*c < '0' || *c > '9')) {
52437c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn                        c++;
52537c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn                    }
52637c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn                    uss += atoi(c);
527c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn                }
528cfc837f7fa43362b5049f648fe1bfdf5a010cc1cDianne Hackborn            }
529b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn        }
530b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn
53137c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn        fclose(fp);
53237c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn    }
533b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn
534c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn    if (outUss != NULL) {
535c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn        if (env->GetArrayLength(outUss) >= 1) {
536c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn            jlong* outUssArray = env->GetLongArrayElements(outUss, 0);
537c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn            if (outUssArray != NULL) {
538c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn                outUssArray[0] = uss;
539c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn            }
540c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn            env->ReleaseLongArrayElements(outUss, outUssArray, 0);
541c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn        }
542c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn    }
543c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn
544b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn    return pss;
545b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn}
546b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn
547b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackbornstatic jlong android_os_Debug_getPss(JNIEnv *env, jobject clazz)
548b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn{
549c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn    return android_os_Debug_getPssPid(env, clazz, getpid(), NULL);
550b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn}
551b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn
552cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackbornenum {
553cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    MEMINFO_TOTAL,
554cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    MEMINFO_FREE,
555cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    MEMINFO_BUFFERS,
556cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    MEMINFO_CACHED,
557cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    MEMINFO_SHMEM,
558cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    MEMINFO_SLAB,
559cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    MEMINFO_SWAP_TOTAL,
560cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    MEMINFO_SWAP_FREE,
561cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    MEMINFO_ZRAM_TOTAL,
562cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    MEMINFO_COUNT
563cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn};
564cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn
5658e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackbornstatic void android_os_Debug_getMemInfo(JNIEnv *env, jobject clazz, jlongArray out)
5668e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn{
5678e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    char buffer[1024];
5688e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    int numFound = 0;
5698e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn
5708e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    if (out == NULL) {
5718e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn        jniThrowNullPointerException(env, "out == null");
5728e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn        return;
5738e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    }
5748e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn
5758e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    int fd = open("/proc/meminfo", O_RDONLY);
5768e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn
5778e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    if (fd < 0) {
578cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn        ALOGW("Unable to open /proc/meminfo: %s\n", strerror(errno));
5798e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn        return;
5808e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    }
5818e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn
582cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    int len = read(fd, buffer, sizeof(buffer)-1);
5838e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    close(fd);
5848e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn
5858e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    if (len < 0) {
586cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn        ALOGW("Empty /proc/meminfo");
5878e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn        return;
5888e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    }
5898e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    buffer[len] = 0;
5908e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn
5918e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    static const char* const tags[] = {
5928e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            "MemTotal:",
5938e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            "MemFree:",
5948e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            "Buffers:",
5958e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            "Cached:",
5968e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            "Shmem:",
5978e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            "Slab:",
598cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn            "SwapTotal:",
599cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn            "SwapFree:",
6008e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            NULL
6018e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    };
6028e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    static const int tagsLen[] = {
6038e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            9,
6048e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            8,
6058e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            8,
6068e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            7,
6078e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            6,
6088e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            5,
609cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn            10,
610cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn            9,
6118e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            0
6128e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    };
613cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    long mem[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
6148e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn
6158e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    char* p = buffer;
616cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    while (*p && numFound < 8) {
6178e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn        int i = 0;
6188e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn        while (tags[i]) {
6198e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            if (strncmp(p, tags[i], tagsLen[i]) == 0) {
6208e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn                p += tagsLen[i];
6218e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn                while (*p == ' ') p++;
6228e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn                char* num = p;
6238e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn                while (*p >= '0' && *p <= '9') p++;
6248e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn                if (*p != 0) {
6258e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn                    *p = 0;
6268e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn                    p++;
6278e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn                }
6288e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn                mem[i] = atoll(num);
6298e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn                numFound++;
6308e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn                break;
6318e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            }
6328e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            i++;
6338e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn        }
6348e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn        while (*p && *p != '\n') {
6358e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            p++;
6368e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn        }
6378e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn        if (*p) p++;
6388e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    }
6398e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn
640cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    fd = open("/sys/block/zram0/mem_used_total", O_RDONLY);
641cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    if (fd >= 0) {
642cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn        len = read(fd, buffer, sizeof(buffer)-1);
643cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn        close(fd);
644cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn        if (len > 0) {
645cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn            buffer[len] = 0;
646cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn            mem[MEMINFO_ZRAM_TOTAL] = atoll(buffer)/1024;
647cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn        }
648cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    }
649cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn
6508e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    int maxNum = env->GetArrayLength(out);
651cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    if (maxNum > MEMINFO_COUNT) {
652cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn        maxNum = MEMINFO_COUNT;
653cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn    }
6548e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    jlong* outArray = env->GetLongArrayElements(out, 0);
6558e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    if (outArray != NULL) {
656cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn        for (int i=0; i<maxNum; i++) {
6578e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            outArray[i] = mem[i];
6588e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn        }
6598e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    }
6608e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    env->ReleaseLongArrayElements(out, outArray, 0);
6618e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn}
6628e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint read_binder_stat(const char* stat)
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FILE* fp = fopen(BINDER_STATS, "r");
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fp == NULL) {
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char line[1024];
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char compare[128];
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int len = snprintf(compare, 128, "proc %d", getpid());
6747c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // loop until we have the block that represents this process
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    do {
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (fgets(line, 1024, fp) == 0) {
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return -1;
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } while (strncmp(compare, line, len));
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6827c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers    // now that we have this process, read until we find the stat that we are looking for
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    len = snprintf(compare, 128, "  %s: ", stat);
6847c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    do {
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (fgets(line, 1024, fp) == 0) {
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return -1;
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } while (strncmp(compare, line, len));
6907c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // we have the line, now increment the line ptr to the value
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* ptr = line + len;
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return atoi(ptr);
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_Debug_getBinderSentTransactions(JNIEnv *env, jobject clazz)
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return read_binder_stat("bcTRANSACTION");
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_getBinderReceivedTransactions(JNIEnv *env, jobject clazz)
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return read_binder_stat("brTRANSACTION");
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// these are implemented in android_util_Binder.cpp
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz);
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz);
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz);
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
71106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
71206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* pulled out of bionic */
71306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenextern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize,
71406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    size_t* infoSize, size_t* totalMemory, size_t* backtraceSize);
71506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenextern "C" void free_malloc_leak_info(uint8_t* info);
71606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#define SIZE_FLAG_ZYGOTE_CHILD  (1<<31)
71706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#define BACKTRACE_SIZE          32
71806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
71906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/*
72006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * This is a qsort() callback.
72106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden *
72206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * See dumpNativeHeap() for comments about the data format and sort order.
72306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden */
72406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenstatic int compareHeapRecords(const void* vrec1, const void* vrec2)
72506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden{
72606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    const size_t* rec1 = (const size_t*) vrec1;
72706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    const size_t* rec2 = (const size_t*) vrec2;
72806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    size_t size1 = *rec1;
72906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    size_t size2 = *rec2;
73006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
73106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    if (size1 < size2) {
73206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        return 1;
73306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    } else if (size1 > size2) {
73406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        return -1;
73506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    }
73606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
73706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    intptr_t* bt1 = (intptr_t*)(rec1 + 2);
73806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    intptr_t* bt2 = (intptr_t*)(rec2 + 2);
73906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    for (size_t idx = 0; idx < BACKTRACE_SIZE; idx++) {
74006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        intptr_t addr1 = bt1[idx];
74106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        intptr_t addr2 = bt2[idx];
74206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        if (addr1 == addr2) {
74306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden            if (addr1 == 0)
74406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden                break;
74506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden            continue;
74606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        }
74706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        if (addr1 < addr2) {
74806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden            return -1;
74906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        } else if (addr1 > addr2) {
75006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden            return 1;
75106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        }
75206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    }
75306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
75406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    return 0;
75506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden}
75606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
75706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/*
75806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * The get_malloc_leak_info() call returns an array of structs that
75906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * look like this:
76006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden *
76106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden *   size_t size
76206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden *   size_t allocations
76306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden *   intptr_t backtrace[32]
76406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden *
76506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * "size" is the size of the allocation, "backtrace" is a fixed-size
76606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * array of function pointers, and "allocations" is the number of
76706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * allocations with the exact same size and backtrace.
76806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden *
76906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * The entries are sorted by descending total size (i.e. size*allocations)
77006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * then allocation count.  For best results with "diff" we'd like to sort
77106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * primarily by individual size then stack trace.  Since the entries are
77206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * fixed-size, and we're allowed (by the current implementation) to mangle
77306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * them, we can do this in place.
77406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden */
77506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenstatic void dumpNativeHeap(FILE* fp)
77606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden{
77706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    uint8_t* info = NULL;
77806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    size_t overallSize, infoSize, totalMemory, backtraceSize;
77906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
78006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory,
78106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        &backtraceSize);
78206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    if (info == NULL) {
78306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        fprintf(fp, "Native heap dump not available. To enable, run these"
78406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden                    " commands (requires root):\n");
78506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        fprintf(fp, "$ adb shell setprop libc.debug.malloc 1\n");
78606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        fprintf(fp, "$ adb shell stop\n");
78706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        fprintf(fp, "$ adb shell start\n");
78806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        return;
78906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    }
79006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    assert(infoSize != 0);
79106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    assert(overallSize % infoSize == 0);
79206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
79306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    fprintf(fp, "Android Native Heap Dump v1.0\n\n");
79406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
79506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    size_t recordCount = overallSize / infoSize;
79606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    fprintf(fp, "Total memory: %zu\n", totalMemory);
79706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    fprintf(fp, "Allocation records: %zd\n", recordCount);
79806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    if (backtraceSize != BACKTRACE_SIZE) {
79906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        fprintf(fp, "WARNING: mismatched backtrace sizes (%d vs. %d)\n",
80006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden            backtraceSize, BACKTRACE_SIZE);
80106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    }
80206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    fprintf(fp, "\n");
80306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
80406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    /* re-sort the entries */
80506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    qsort(info, recordCount, infoSize, compareHeapRecords);
80606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
80706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    /* dump the entries to the file */
80806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    const uint8_t* ptr = info;
80906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    for (size_t idx = 0; idx < recordCount; idx++) {
81006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        size_t size = *(size_t*) ptr;
81106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        size_t allocations = *(size_t*) (ptr + sizeof(size_t));
81206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        intptr_t* backtrace = (intptr_t*) (ptr + sizeof(size_t) * 2);
81306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
81406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        fprintf(fp, "z %d  sz %8zu  num %4zu  bt",
81506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden                (size & SIZE_FLAG_ZYGOTE_CHILD) != 0,
81606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden                size & ~SIZE_FLAG_ZYGOTE_CHILD,
81706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden                allocations);
81806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        for (size_t bt = 0; bt < backtraceSize; bt++) {
81906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden            if (backtrace[bt] == 0) {
82006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden                break;
82106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden            } else {
82206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden                fprintf(fp, " %08x", backtrace[bt]);
82306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden            }
82406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        }
82506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        fprintf(fp, "\n");
82606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
82706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        ptr += infoSize;
82806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    }
82906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
83006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    free_malloc_leak_info(info);
831393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom
832393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom    fprintf(fp, "MAPS\n");
833393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom    const char* maps = "/proc/self/maps";
834393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom    FILE* in = fopen(maps, "r");
835393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom    if (in == NULL) {
836393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom        fprintf(fp, "Could not open %s\n", maps);
837393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom        return;
838393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom    }
839393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom    char buf[BUFSIZ];
840393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom    while (size_t n = fread(buf, sizeof(char), BUFSIZ, in)) {
841393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom        fwrite(buf, sizeof(char), n, fp);
842393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom    }
843393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom    fclose(in);
844393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom
845393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom    fprintf(fp, "END\n");
84606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden}
84706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
84806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/*
84906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * Dump the native heap, writing human-readable output to the specified
85006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * file descriptor.
85106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden */
85206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenstatic void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject clazz,
85306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    jobject fileDescriptor)
85406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden{
85506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    if (fileDescriptor == NULL) {
8567c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers        jniThrowNullPointerException(env, "fd == null");
85706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        return;
85806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    }
85906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    int origFd = jniGetFDFromFileDescriptor(env, fileDescriptor);
86006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    if (origFd < 0) {
86106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        jniThrowRuntimeException(env, "Invalid file descriptor");
86206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        return;
86306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    }
86406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
86506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    /* dup() the descriptor so we don't close the original with fclose() */
86606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    int fd = dup(origFd);
86706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    if (fd < 0) {
8688564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("dup(%d) failed: %s\n", origFd, strerror(errno));
86906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        jniThrowRuntimeException(env, "dup() failed");
87006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        return;
87106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    }
87206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
87306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    FILE* fp = fdopen(fd, "w");
87406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    if (fp == NULL) {
8758564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("fdopen(%d) failed: %s\n", fd, strerror(errno));
87606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        close(fd);
87706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        jniThrowRuntimeException(env, "fdopen() failed");
87806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden        return;
87906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    }
88006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
8815baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("Native heap dump starting...\n");
88206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    dumpNativeHeap(fp);
8835baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("Native heap dump complete.\n");
88406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
88506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    fclose(fp);
88606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden}
88706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
88806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden
889f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackbornstatic void android_os_Debug_dumpNativeBacktraceToFile(JNIEnv* env, jobject clazz,
890f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    jint pid, jstring fileName)
891f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn{
892f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    if (fileName == NULL) {
8937c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers        jniThrowNullPointerException(env, "file == null");
894f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn        return;
895f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    }
896f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    const jchar* str = env->GetStringCritical(fileName, 0);
897f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    String8 fileName8;
898f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    if (str) {
899f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn        fileName8 = String8(str, env->GetStringLength(fileName));
900f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn        env->ReleaseStringCritical(fileName, str);
901f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    }
902f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn
903f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    int fd = open(fileName8.string(), O_CREAT | O_WRONLY | O_NOFOLLOW, 0666);  /* -rw-rw-rw- */
904f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    if (fd < 0) {
905f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn        fprintf(stderr, "Can't open %s: %s\n", fileName8.string(), strerror(errno));
906f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn        return;
907f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    }
908f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn
909f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    if (lseek(fd, 0, SEEK_END) < 0) {
910f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn        fprintf(stderr, "lseek: %s\n", strerror(errno));
911f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    } else {
912f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn        dump_backtrace_to_file(pid, fd);
913f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    }
914f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn
915f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    close(fd);
916f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn}
917f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * JNI registration.
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMethods[] = {
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getNativeHeapSize",      "()J",
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*) android_os_Debug_getNativeHeapSize },
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getNativeHeapAllocatedSize", "()J",
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*) android_os_Debug_getNativeHeapAllocatedSize },
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getNativeHeapFreeSize",  "()J",
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*) android_os_Debug_getNativeHeapFreeSize },
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getMemoryInfo",          "(Landroid/os/Debug$MemoryInfo;)V",
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*) android_os_Debug_getDirtyPages },
9313025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn    { "getMemoryInfo",          "(ILandroid/os/Debug$MemoryInfo;)V",
9323025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn            (void*) android_os_Debug_getDirtyPagesPid },
933b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn    { "getPss",                 "()J",
934b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn            (void*) android_os_Debug_getPss },
935c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn    { "getPss",                 "(I[J)J",
936b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn            (void*) android_os_Debug_getPssPid },
9378e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn    { "getMemInfo",             "([J)V",
9388e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn            (void*) android_os_Debug_getMemInfo },
93906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden    { "dumpNativeHeap",         "(Ljava/io/FileDescriptor;)V",
94006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden            (void*) android_os_Debug_dumpNativeHeap },
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getBinderSentTransactions", "()I",
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*) android_os_Debug_getBinderSentTransactions },
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getBinderReceivedTransactions", "()I",
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*) android_os_getBinderReceivedTransactions },
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getBinderLocalObjectCount", "()I",
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*)android_os_Debug_getLocalObjectCount },
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getBinderProxyObjectCount", "()I",
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*)android_os_Debug_getProxyObjectCount },
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "getBinderDeathObjectCount", "()I",
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (void*)android_os_Debug_getDeathObjectCount },
951f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    { "dumpNativeBacktraceToFile", "(ILjava/lang/String;)V",
952f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn            (void*)android_os_Debug_dumpNativeBacktraceToFile },
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_os_Debug(JNIEnv *env)
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
9575b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    int err = memtrack_init();
9585b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    if (err != 0) {
9595b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        memtrackLoaded = false;
9605b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        ALOGE("failed to load memtrack module: %d", err);
9615b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    } else {
9625b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski        memtrackLoaded = true;
9635b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski    }
9645b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jclass clazz = env->FindClass("android/os/Debug$MemoryInfo");
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9677c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers    // Sanity check the number of other statistics expected in Java matches here.
9687c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers    jfieldID numOtherStats_field = env->GetStaticFieldID(clazz, "NUM_OTHER_STATS", "I");
9697c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers    jint numOtherStats = env->GetStaticIntField(clazz, numOtherStats_field);
9703c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    jfieldID numDvkStats_field = env->GetStaticFieldID(clazz, "NUM_DVK_STATS", "I");
9713c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    jint numDvkStats = env->GetStaticIntField(clazz, numDvkStats_field);
9727c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers    int expectedNumOtherStats = _NUM_HEAP - _NUM_CORE_HEAP;
9733c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum    if ((numOtherStats + numDvkStats) != expectedNumOtherStats) {
9747c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers        jniThrowExceptionFmt(env, "java/lang/RuntimeException",
9753c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                             "android.os.Debug.Meminfo.NUM_OTHER_STATS+android.os.Debug.Meminfo.NUM_DVK_STATS=%d expected %d",
9763c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                             numOtherStats+numDvkStats, expectedNumOtherStats);
9777c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers        return JNI_ERR;
9787c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers    }
9797c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers
9807c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers    otherStats_field = env->GetFieldID(clazz, "otherStats", "[I");
9817c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers
9820e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    for (int i=0; i<_NUM_CORE_HEAP; i++) {
9830e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        stat_fields[i].pss_field =
9840e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn                env->GetFieldID(clazz, stat_field_names[i].pss_name, "I");
9853c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum        stat_fields[i].pssSwappable_field =
9863c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                env->GetFieldID(clazz, stat_field_names[i].pssSwappable_name, "I");
9870e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        stat_fields[i].privateDirty_field =
9880e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn                env->GetFieldID(clazz, stat_field_names[i].privateDirty_name, "I");
9890e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn        stat_fields[i].sharedDirty_field =
9900e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn                env->GetFieldID(clazz, stat_field_names[i].sharedDirty_name, "I");
9913c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum        stat_fields[i].privateClean_field =
9923c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum                env->GetFieldID(clazz, stat_field_names[i].privateClean_name, "I");
9933a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum        stat_fields[i].sharedClean_field =
9943a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum                env->GetFieldID(clazz, stat_field_names[i].sharedClean_name, "I");
9958883ced18ac25199330843964634fdf70647a127Dianne Hackborn        stat_fields[i].swappedOut_field =
9968883ced18ac25199330843964634fdf70647a127Dianne Hackborn                env->GetFieldID(clazz, stat_field_names[i].swappedOut_name, "I");
9970e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn    }
9980e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods));
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
100206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden}; // namespace android
1003