am 14d0ab55: am de3c20bc: Merge "Track stack memory in MemoryInfo."

* commit '14d0ab55e983d314128bb7b3293023f4a237d991':
  Track stack memory in MemoryInfo.
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 88ebdd5..2e77237 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -130,7 +130,7 @@
         public int otherSharedDirty;
 
         /** @hide */
-        public static final int NUM_OTHER_STATS = 9;
+        public static final int NUM_OTHER_STATS = 10;
 
         private int[] otherStats = new int[NUM_OTHER_STATS*3];
 
@@ -177,15 +177,16 @@
         /* @hide */
         public static String getOtherLabel(int which) {
             switch (which) {
-                case 0: return "Cursor";
-                case 1: return "Ashmem";
-                case 2: return "Other dev";
-                case 3: return ".so mmap";
-                case 4: return ".jar mmap";
-                case 5: return ".apk mmap";
-                case 6: return ".ttf mmap";
-                case 7: return ".dex mmap";
-                case 8: return "Other mmap";
+                case 0: return "Stack";
+                case 1: return "Cursor";
+                case 2: return "Ashmem";
+                case 3: return "Other dev";
+                case 4: return ".so mmap";
+                case 5: return ".jar mmap";
+                case 6: return ".apk mmap";
+                case 7: return ".ttf mmap";
+                case 8: return ".dex mmap";
+                case 9: return "Other mmap";
                 default: return "????";
             }
         }
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 6e21a11..2883c10 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -43,6 +43,7 @@
     HEAP_UNKNOWN,
     HEAP_DALVIK,
     HEAP_NATIVE,
+    HEAP_STACK,
     HEAP_CURSOR,
     HEAP_ASHMEM,
     HEAP_UNKNOWN_DEV,
@@ -109,7 +110,7 @@
 
 static jlong android_os_Debug_getNativeHeapFreeSize(JNIEnv *env, jobject clazz)
 {
-#ifdef HAVE_MALLOC_H    
+#ifdef HAVE_MALLOC_H
     struct mallinfo info = mallinfo();
     return (jlong) info.fordblks;
 #else
@@ -164,6 +165,8 @@
                 whichHeap = HEAP_NATIVE;
             } else if (strstr(name, "/dev/ashmem/dalvik-") == name) {
                 whichHeap = HEAP_DALVIK;
+            } else if (strstr(name, "[stack") == name) {
+                whichHeap = HEAP_STACK;
             } else if (strstr(name, "/dev/ashmem/CursorWindow") == name) {
                 whichHeap = HEAP_CURSOR;
             } else if (strstr(name, "/dev/ashmem/") == name) {
@@ -191,7 +194,7 @@
 
         //ALOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap,
         //    isSqliteHeap, line);
-            
+
         while (true) {
             if (fgets(line, 1024, fp) == 0) {
                 done = true;
@@ -233,7 +236,7 @@
 {
     char tmp[128];
     FILE *fp;
-    
+
     sprintf(tmp, "/proc/%d/smaps", pid);
     fp = fopen(tmp, "r");
     if (fp == 0) return;
@@ -247,7 +250,7 @@
 {
     stats_t stats[_NUM_HEAP];
     memset(&stats, 0, sizeof(stats));
-    
+
     load_maps(pid, stats);
 
     for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) {
@@ -261,9 +264,9 @@
         env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty);
         env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty);
     }
-    
+
     jintArray otherIntArray = (jintArray)env->GetObjectField(object, otherStats_field);
-    
+
     jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0);
     if (otherArray == NULL) {
         return;
@@ -328,7 +331,7 @@
 
     char compare[128];
     int len = snprintf(compare, 128, "proc %d", getpid());
-    
+
     // loop until we have the block that represents this process
     do {
         if (fgets(line, 1024, fp) == 0) {
@@ -336,15 +339,15 @@
         }
     } while (strncmp(compare, line, len));
 
-    // now that we have this process, read until we find the stat that we are looking for 
+    // now that we have this process, read until we find the stat that we are looking for
     len = snprintf(compare, 128, "  %s: ", stat);
-    
+
     do {
         if (fgets(line, 1024, fp) == 0) {
             return -1;
         }
     } while (strncmp(compare, line, len));
-    
+
     // we have the line, now increment the line ptr to the value
     char* ptr = line + len;
     return atoi(ptr);
@@ -510,7 +513,7 @@
     jobject fileDescriptor)
 {
     if (fileDescriptor == NULL) {
-        jniThrowNullPointerException(env, NULL);
+        jniThrowNullPointerException(env, "fd == null");
         return;
     }
     int origFd = jniGetFDFromFileDescriptor(env, fileDescriptor);
@@ -547,7 +550,7 @@
     jint pid, jstring fileName)
 {
     if (fileName == NULL) {
-        jniThrowNullPointerException(env, NULL);
+        jniThrowNullPointerException(env, "file == null");
         return;
     }
     const jchar* str = env->GetStringCritical(fileName, 0);
@@ -611,6 +614,19 @@
 {
     jclass clazz = env->FindClass("android/os/Debug$MemoryInfo");
 
+    // Sanity check the number of other statistics expected in Java matches here.
+    jfieldID numOtherStats_field = env->GetStaticFieldID(clazz, "NUM_OTHER_STATS", "I");
+    jint numOtherStats = env->GetStaticIntField(clazz, numOtherStats_field);
+    int expectedNumOtherStats = _NUM_HEAP - _NUM_CORE_HEAP;
+    if (numOtherStats != expectedNumOtherStats) {
+        jniThrowExceptionFmt(env, "java/lang/RuntimeException",
+                             "android.os.Debug.Meminfo.NUM_OTHER_STATS=%d expected %d",
+                             numOtherStats, expectedNumOtherStats);
+        return JNI_ERR;
+    }
+
+    otherStats_field = env->GetFieldID(clazz, "otherStats", "[I");
+
     for (int i=0; i<_NUM_CORE_HEAP; i++) {
         stat_fields[i].pss_field =
                 env->GetFieldID(clazz, stat_field_names[i].pss_name, "I");
@@ -620,8 +636,6 @@
                 env->GetFieldID(clazz, stat_field_names[i].sharedDirty_name, "I");
     }
 
-    otherStats_field = env->GetFieldID(clazz, "otherStats", "[I");
-
     return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods));
 }