From d68c637a36b65d0bce893991e9c910efbc06239a Mon Sep 17 00:00:00 2001
From: eapen <zhangyipeng7@huawei.com>
Date: Mon, 12 Dec 2022 16:10:41 +0800
Subject: [PATCH 10/33] I68TO2: 8257695: [linux] Add process-memory information to
 hs-err and VM.info
---
 hotspot/src/os/linux/vm/os_linux.cpp | 67 ++++++++++++++++++++++++++++++++++--
 hotspot/src/os/linux/vm/os_linux.hpp |  3 +-
 2 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index 6dbedf5..4c265d5 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -103,6 +103,9 @@
 # include <stdint.h>
 # include <inttypes.h>
 # include <sys/ioctl.h>
+#ifdef __GLIBC__
+# include <malloc.h>
+#endif

 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC

@@ -2216,7 +2219,10 @@ void os::print_os_info(outputStream* st) {

   os::Posix::print_load_average(st);

-  os::Linux::print_full_memory_info(st);
+  os::Linux::print_system_memory_info(st);
+  st->cr();
+
+  os::Linux::print_process_memory_info(st);

   os::Linux::print_container_info(st);
 }
@@ -2278,12 +2284,69 @@ void os::Linux::print_libversion_info(outputStream* st) {
   st->cr();
 }

-void os::Linux::print_full_memory_info(outputStream* st) {
+void os::Linux::print_system_memory_info(outputStream* st) {
    st->print("\n/proc/meminfo:\n");
    _print_ascii_file("/proc/meminfo", st);
    st->cr();
 }

+void os::Linux::print_process_memory_info(outputStream* st) {
+
+  st->print_cr("Process Memory:");
+
+  // Print virtual and resident set size; peak values; swap; and for
+  //  rss its components if the kernel is recent enough.
+  ssize_t vmsize = -1, vmpeak = -1, vmswap = -1,
+      vmrss = -1, vmhwm = -1, rssanon = -1, rssfile = -1, rssshmem = -1;
+  const int num_values = 8;
+  int num_found = 0;
+  FILE* f = ::fopen("/proc/self/status", "r");
+  char buf[256];
+  while (::fgets(buf, sizeof(buf), f) != NULL && num_found < num_values) {
+    if ( (vmsize == -1    && sscanf(buf, "VmSize: " SSIZE_FORMAT " kB", &vmsize) == 1) ||
+         (vmpeak == -1    && sscanf(buf, "VmPeak: " SSIZE_FORMAT " kB", &vmpeak) == 1) ||
+         (vmswap == -1    && sscanf(buf, "VmSwap: " SSIZE_FORMAT " kB", &vmswap) == 1) ||
+         (vmhwm == -1     && sscanf(buf, "VmHWM: " SSIZE_FORMAT " kB", &vmhwm) == 1) ||
+         (vmrss == -1     && sscanf(buf, "VmRSS: " SSIZE_FORMAT " kB", &vmrss) == 1) ||
+         (rssanon == -1   && sscanf(buf, "RssAnon: " SSIZE_FORMAT " kB", &rssanon) == 1) ||
+         (rssfile == -1   && sscanf(buf, "RssFile: " SSIZE_FORMAT " kB", &rssfile) == 1) ||
+         (rssshmem == -1  && sscanf(buf, "RssShmem: " SSIZE_FORMAT " kB", &rssshmem) == 1)
+         )
+    {
+      num_found ++;
+    }
+  }
+  st->print_cr("Virtual Size: " SSIZE_FORMAT "K (peak: " SSIZE_FORMAT "K)", vmsize, vmpeak);
+  st->print("Resident Set Size: " SSIZE_FORMAT "K (peak: " SSIZE_FORMAT "K)", vmrss, vmhwm);
+  if (rssanon != -1) { // requires kernel >= 4.5
+    st->print(" (anon: " SSIZE_FORMAT "K, file: " SSIZE_FORMAT "K, shmem: " SSIZE_FORMAT "K)",
+                rssanon, rssfile, rssshmem);
+  }
+  st->cr();
+  if (vmswap != -1) { // requires kernel >= 2.6.34
+    st->print_cr("Swapped out: " SSIZE_FORMAT "K", vmswap);
+  }
+
+  // Print glibc outstanding allocations.
+  // (note: there is no implementation of mallinfo for muslc)
+#ifdef __GLIBC__
+  struct mallinfo mi = ::mallinfo();
+
+  // mallinfo is an old API. Member names mean next to nothing and, beyond that, are int.
+  // So values may have wrapped around. Still useful enough to see how much glibc thinks
+  // we allocated.
+  const size_t total_allocated = (size_t)(unsigned)mi.uordblks;
+  st->print("C-Heap outstanding allocations: " SIZE_FORMAT "K", total_allocated / K);
+  // Since mallinfo members are int, glibc values may have wrapped. Warn about this.
+  if ((vmrss * K) > UINT_MAX && (vmrss * K) > (total_allocated + UINT_MAX)) {
+    st->print(" (may have wrapped)");
+  }
+  st->cr();
+
+#endif // __GLIBC__
+
+}
+
 void os::Linux::print_container_info(outputStream* st) {
 if (!OSContainer::is_containerized()) {
     return;
diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp
index c674882..066b03a 100644
--- a/hotspot/src/os/linux/vm/os_linux.hpp
+++ b/hotspot/src/os/linux/vm/os_linux.hpp
@@ -120,7 +120,8 @@ class Linux {
   static bool release_memory_special_shm(char* base, size_t bytes);
   static bool release_memory_special_huge_tlbfs(char* base, size_t bytes);

-  static void print_full_memory_info(outputStream* st);
+  static void print_process_memory_info(outputStream* st);
+  static void print_system_memory_info(outputStream* st);
   static void print_container_info(outputStream* st);
   static void print_distro_info(outputStream* st);
   static void print_libversion_info(outputStream* st);
--
1.8.3.1
