Snap for 7302914 from d5c744b9de6a02b907c2ab19d28bdc916e77863e to sc-release

Change-Id: I43beaeda2b143cbc5d49e6266a8807ae31e26b9b
diff --git a/include/meminfo/meminfo.h b/include/meminfo/meminfo.h
index 79ae619..545f27d 100644
--- a/include/meminfo/meminfo.h
+++ b/include/meminfo/meminfo.h
@@ -40,6 +40,14 @@
     uint64_t shared_clean;
     uint64_t shared_dirty;
 
+    uint64_t anon_huge_pages;
+    uint64_t shmem_pmd_mapped;
+    uint64_t file_pmd_mapped;
+    uint64_t shared_hugetlb;
+    uint64_t private_hugetlb;
+
+    uint64_t thp;
+
     MemUsage()
         : vss(0),
           rss(0),
@@ -50,7 +58,13 @@
           private_clean(0),
           private_dirty(0),
           shared_clean(0),
-          shared_dirty(0) {}
+          shared_dirty(0),
+          anon_huge_pages(0),
+          shmem_pmd_mapped(0),
+          file_pmd_mapped(0),
+          shared_hugetlb(0),
+          private_hugetlb(0),
+          thp(0) {}
 
     ~MemUsage() = default;
 
diff --git a/meminfo_private.h b/meminfo_private.h
index df5699c..e087fb8 100644
--- a/meminfo_private.h
+++ b/meminfo_private.h
@@ -24,11 +24,15 @@
 #include <meminfo/procmeminfo.h>
 #include <meminfo/sysmeminfo.h>
 
-// Macros to do per-page flag manipulation
 #define _BITS(x, offset, bits) (((x) >> (offset)) & ((1LL << (bits)) - 1))
+
+// Macros to do per-page pagemap data manipulation
 #define PAGE_PRESENT(x) (_BITS(x, 63, 1))
 #define PAGE_SWAPPED(x) (_BITS(x, 62, 1))
 #define PAGE_SHIFT(x) (_BITS(x, 55, 6))
 #define PAGE_PFN(x) (_BITS(x, 0, 55))
 #define PAGE_SWAP_OFFSET(x) (_BITS(x, 5, 50))
 #define PAGE_SWAP_TYPE(x) (_BITS(x, 0, 5))
+
+// Macros to do per-page kpageflags data manipulation
+#define KPAGEFLAG_THP(x) (_BITS(x, 22, 1))
diff --git a/procmeminfo.cpp b/procmeminfo.cpp
index ea4b304..af64f86 100644
--- a/procmeminfo.cpp
+++ b/procmeminfo.cpp
@@ -84,6 +84,8 @@
                     uint64_t prdi = strtoull(c, nullptr, 10);
                     stats->private_dirty = prdi;
                     stats->uss += prdi;
+                } else if (strncmp(field, "Private_Hugetlb:", 16) == 0) {
+                    stats->private_hugetlb = strtoull(c, nullptr, 10);
                 }
                 break;
             case 'S':
@@ -97,6 +99,10 @@
                     stats->swap = strtoull(c, nullptr, 10);
                 } else if (strncmp(field, "SwapPss:", 8) == 0) {
                     stats->swap_pss = strtoull(c, nullptr, 10);
+                } else if (strncmp(field, "ShmemPmdMapped:", 15) == 0) {
+                    stats->shmem_pmd_mapped = strtoull(c, nullptr, 10);
+                } else if (strncmp(field, "Shared_Hugetlb:", 15) == 0) {
+                    stats->shared_hugetlb = strtoull(c, nullptr, 10);
                 }
                 break;
             case 'R':
@@ -104,6 +110,16 @@
                     stats->rss = strtoull(c, nullptr, 10);
                 }
                 break;
+            case 'A':
+                if (strncmp(field, "AnonHugePages:", 14) == 0) {
+                    stats->anon_huge_pages = strtoull(c, nullptr, 10);
+                }
+                break;
+            case 'F':
+                if (strncmp(field, "FilePmdMapped:", 14) == 0) {
+                    stats->file_pmd_mapped = strtoull(c, nullptr, 10);
+                }
+                break;
         }
         return true;
     }
@@ -418,6 +434,10 @@
             return false;
         }
 
+        if (KPAGEFLAG_THP(cur_page_flags)) {
+            vma.usage.thp += pagesz;
+        }
+
         // skip unwanted pages from the count
         if ((cur_page_flags & pgflags_mask_) != pgflags_) continue;
 
diff --git a/tools/procmem.cpp b/tools/procmem.cpp
index b245f2a..1fe8d50 100644
--- a/tools/procmem.cpp
+++ b/tools/procmem.cpp
@@ -60,25 +60,25 @@
 
 static void print_separator(std::stringstream& ss) {
     if (show_wss) {
-        ss << ::android::base::StringPrintf("%7s  %7s  %7s  %7s  %7s  %7s  %7s  %7s  %s\n",
+        ss << ::android::base::StringPrintf("%7s  %7s  %7s  %7s  %7s  %7s  %7s  %7s  %7s  %s\n",
                                             "-------", "-------", "-------", "-------", "-------",
-                                            "-------", "-------", "-------", "");
+                                            "-------", "-------", "-------", "-------", "");
         return;
     }
-    ss << ::android::base::StringPrintf("%7s  %7s  %7s  %7s  %7s  %7s  %7s  %7s  %7s  %s\n",
+    ss << ::android::base::StringPrintf("%7s  %7s  %7s  %7s  %7s  %7s  %7s  %7s  %7s  %7s  %s\n",
                                         "-------", "-------", "-------", "-------", "-------",
-                                        "-------", "-------", "-------", "-------", "");
+                                        "-------", "-------", "-------", "-------", "-------", "");
 }
 
 static void print_header(std::stringstream& ss) {
     if (show_wss) {
-        ss << ::android::base::StringPrintf("%7s  %7s  %7s  %7s  %7s  %7s  %7s  %7s  %s\n", "WRss",
-                                            "WPss", "WUss", "WShCl", "WShDi", "WPrCl", "WPrDi",
-                                            "Flags", "Name");
-    } else {
         ss << ::android::base::StringPrintf("%7s  %7s  %7s  %7s  %7s  %7s  %7s  %7s  %7s  %s\n",
-                                            "Vss", "Rss", "Pss", "Uss", "ShCl", "ShDi", "PrCl",
-                                            "PrDi", "Flags", "Name");
+                                            "WRss", "WPss", "WUss", "WShCl", "WShDi", "WPrCl",
+                                            "WPrDi", "THP", "Flags", "Name");
+    } else {
+        ss << ::android::base::StringPrintf(
+                "%7s  %7s  %7s  %7s  %7s  %7s  %7s  %7s  %7s  %7s  %s\n", "Vss", "Rss", "Pss",
+                "Uss", "ShCl", "ShDi", "PrCl", "PrDi", "THP", "Flags", "Name");
     }
     print_separator(ss);
 }
@@ -88,11 +88,12 @@
         ss << ::android::base::StringPrintf("%6" PRIu64 "K  ", stats.vss / 1024);
     }
 
-    ss << ::android::base::StringPrintf("%6" PRIu64 "K  %6" PRIu64 "K  %6" PRIu64 "K  %6" PRIu64
-                                        "K  %6" PRIu64 "K  %6" PRIu64 "K  %6" PRIu64 "K  ",
-                                        stats.rss / 1024, stats.pss / 1024, stats.uss / 1024,
-                                        stats.shared_clean / 1024, stats.shared_dirty / 1024,
-                                        stats.private_clean / 1024, stats.private_dirty / 1024);
+    ss << ::android::base::StringPrintf(
+            "%6" PRIu64 "K  %6" PRIu64 "K  %6" PRIu64 "K  %6" PRIu64 "K  %6" PRIu64 "K  %6" PRIu64
+            "K  %6" PRIu64 "K  %6" PRIu64 "K ",
+            stats.rss / 1024, stats.pss / 1024, stats.uss / 1024, stats.shared_clean / 1024,
+            stats.shared_dirty / 1024, stats.private_clean / 1024, stats.private_dirty / 1024,
+            stats.thp / 1024);
 }
 
 static int show(const MemUsage& proc_stats, const std::vector<Vma>& maps) {
diff --git a/tools/showmap.cpp b/tools/showmap.cpp
index 72ab0f3..36739b1 100644
--- a/tools/showmap.cpp
+++ b/tools/showmap.cpp
@@ -114,8 +114,16 @@
             it->vma.usage.private_dirty += current.vma.usage.private_dirty;
             it->vma.usage.swap += current.vma.usage.swap;
             it->vma.usage.swap_pss += current.vma.usage.swap_pss;
+
+            it->vma.usage.anon_huge_pages += current.vma.usage.anon_huge_pages;
+            it->vma.usage.shmem_pmd_mapped += current.vma.usage.shmem_pmd_mapped;
+            it->vma.usage.file_pmd_mapped += current.vma.usage.file_pmd_mapped;
+            it->vma.usage.shared_hugetlb += current.vma.usage.shared_hugetlb;
+            it->vma.usage.private_hugetlb += current.vma.usage.private_hugetlb;
+
             it->is_bss &= current.is_bss;
             it->count++;
+
             break;
         }
 
@@ -134,8 +142,11 @@
     const char* addr1 = g_show_addr ? "           start              end " : "";
     const char* addr2 = g_show_addr ? "            addr             addr " : "";
 
-    printf("%s virtual                     shared   shared  private  private\n", addr1);
-    printf("%s    size      RSS      PSS    clean    dirty    clean    dirty     swap  swapPSS",
+    printf("%s virtual                     shared   shared  private  private                   "
+           "Anon      Shmem     File       Shared   Private\n",
+           addr1);
+    printf("%s    size      RSS      PSS    clean    dirty    clean    dirty     swap  swapPSS "
+           "HugePages PmdMapped PmdMapped  Hugetlb  Hugetlb",
            addr2);
     if (!g_verbose && !g_show_addr) {
         printf("   # ");
@@ -150,7 +161,8 @@
     if (g_show_addr) {
         printf("-------- -------- ");
     }
-    printf("-------- -------- -------- -------- -------- -------- -------- -------- -------- ");
+    printf("-------- -------- -------- -------- -------- -------- -------- -------- -------- "
+           "--------- --------- --------- -------- -------- ");
     if (!g_verbose && !g_show_addr) {
         printf("---- ");
     }
@@ -169,10 +181,13 @@
         }
     }
     printf("%8" PRIu64 " %8" PRIu64 " %8" PRIu64 " %8" PRIu64 " %8" PRIu64 " %8" PRIu64 " %8" PRIu64
-           " %8" PRIu64 " %8" PRIu64 " ",
+           " %8" PRIu64 " %8" PRIu64 " %9" PRIu64 " %9" PRIu64 " %9" PRIu64 " %8" PRIu64
+           " %8" PRIu64 " ",
            v.vma.usage.vss, v.vma.usage.rss, v.vma.usage.pss, v.vma.usage.shared_clean,
            v.vma.usage.shared_dirty, v.vma.usage.private_clean, v.vma.usage.private_dirty,
-           v.vma.usage.swap, v.vma.usage.swap_pss);
+           v.vma.usage.swap, v.vma.usage.swap_pss, v.vma.usage.anon_huge_pages,
+           v.vma.usage.shmem_pmd_mapped, v.vma.usage.file_pmd_mapped, v.vma.usage.shared_hugetlb,
+           v.vma.usage.private_hugetlb);
     if (!g_verbose && !g_show_addr) {
         printf("%4" PRIu32 " ", v.count);
     }