diff src/share/vm/runtime/os.cpp @ 6197:d2a62e0f25eb

6995781: Native Memory Tracking (Phase 1) 7151532: DCmd for hotspot native memory tracking Summary: Implementation of native memory tracking phase 1, which tracks VM native memory usage, and related DCmd Reviewed-by: acorn, coleenp, fparain
author zgu
date Thu, 28 Jun 2012 17:03:16 -0400
parents 94ec88ca68e2
children 1d7922586cf6
line wrap: on
line diff
--- a/src/share/vm/runtime/os.cpp	Wed Jun 27 15:23:36 2012 +0200
+++ b/src/share/vm/runtime/os.cpp	Thu Jun 28 17:03:16 2012 -0400
@@ -45,6 +45,7 @@
 #include "runtime/os.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "services/attachListener.hpp"
+#include "services/memTracker.hpp"
 #include "services/threadService.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/events.hpp"
@@ -433,9 +434,9 @@
 
 // --------------------- heap allocation utilities ---------------------
 
-char *os::strdup(const char *str) {
+char *os::strdup(const char *str, MEMFLAGS flags) {
   size_t size = strlen(str);
-  char *dup_str = (char *)malloc(size + 1);
+  char *dup_str = (char *)malloc(size + 1, flags);
   if (dup_str == NULL) return NULL;
   strcpy(dup_str, str);
   return dup_str;
@@ -559,7 +560,7 @@
 }
 #endif
 
-void* os::malloc(size_t size) {
+void* os::malloc(size_t size, MEMFLAGS memflags, address caller) {
   NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
   NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
 
@@ -571,6 +572,7 @@
 
   NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
   u_char* ptr = (u_char*)::malloc(size + space_before + space_after);
+
 #ifdef ASSERT
   if (ptr == NULL) return NULL;
   if (MallocCushion) {
@@ -589,18 +591,29 @@
   }
   debug_only(if (paranoid) verify_block(memblock));
   if (PrintMalloc && tty != NULL) tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
+
+  // we do not track MallocCushion memory
+  if (MemTracker::is_on()) {
+    MemTracker::record_malloc((address)memblock, size, memflags, caller == 0 ? CALLER_PC : caller);
+  }
+
   return memblock;
 }
 
 
-void* os::realloc(void *memblock, size_t size) {
+void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, address caller) {
 #ifndef ASSERT
   NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
   NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
-  return ::realloc(memblock, size);
+  void* ptr = ::realloc(memblock, size);
+  if (ptr != NULL && MemTracker::is_on()) {
+    MemTracker::record_realloc((address)memblock, (address)ptr, size, memflags,
+     caller == 0 ? CALLER_PC : caller);
+  }
+  return ptr;
 #else
   if (memblock == NULL) {
-    return malloc(size);
+    return malloc(size, memflags, (caller == 0 ? CALLER_PC : caller));
   }
   if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
     tty->print_cr("os::realloc caught " PTR_FORMAT, memblock);
@@ -610,7 +623,7 @@
   NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
   if (size == 0) return NULL;
   // always move the block
-  void* ptr = malloc(size);
+  void* ptr = malloc(size, memflags, caller == 0 ? CALLER_PC : caller);
   if (PrintMalloc) tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
   // Copy to new memory if malloc didn't fail
   if ( ptr != NULL ) {
@@ -627,7 +640,7 @@
 }
 
 
-void  os::free(void *memblock) {
+void  os::free(void *memblock, MEMFLAGS memflags) {
   NOT_PRODUCT(inc_stat_counter(&num_frees, 1));
 #ifdef ASSERT
   if (memblock == NULL) return;
@@ -660,6 +673,8 @@
     fprintf(stderr, "os::free " PTR_FORMAT "\n", (uintptr_t)memblock);
   }
 #endif
+  MemTracker::record_free((address)memblock, memflags);
+
   ::free((char*)memblock - space_before);
 }
 
@@ -1048,7 +1063,7 @@
         ++formatted_path_len;
     }
 
-    char* formatted_path = NEW_C_HEAP_ARRAY(char, formatted_path_len + 1);
+    char* formatted_path = NEW_C_HEAP_ARRAY(char, formatted_path_len + 1, mtInternal);
     if (formatted_path == NULL) {
         return NULL;
     }
@@ -1127,7 +1142,7 @@
     return NULL;
   }
   const char psepchar = *os::path_separator();
-  char* inpath = (char*)NEW_C_HEAP_ARRAY(char, strlen(path) + 1);
+  char* inpath = (char*)NEW_C_HEAP_ARRAY(char, strlen(path) + 1, mtInternal);
   if (inpath == NULL) {
     return NULL;
   }
@@ -1140,7 +1155,7 @@
     p++;
     p = strchr(p, psepchar);
   }
-  char** opath = (char**) NEW_C_HEAP_ARRAY(char*, count);
+  char** opath = (char**) NEW_C_HEAP_ARRAY(char*, count, mtInternal);
   if (opath == NULL) {
     return NULL;
   }
@@ -1153,7 +1168,7 @@
       return NULL;
     }
     // allocate the string and add terminator storage
-    char* s  = (char*)NEW_C_HEAP_ARRAY(char, len + 1);
+    char* s  = (char*)NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
     if (s == NULL) {
       return NULL;
     }
@@ -1162,7 +1177,7 @@
     opath[i] = s;
     p += len + 1;
   }
-  FREE_C_HEAP_ARRAY(char, inpath);
+  FREE_C_HEAP_ARRAY(char, inpath, mtInternal);
   *n = count;
   return opath;
 }
@@ -1366,3 +1381,97 @@
 
   return (int) i;
 }
+
+bool os::create_stack_guard_pages(char* addr, size_t bytes) {
+  return os::pd_create_stack_guard_pages(addr, bytes);
+}
+
+
+char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
+  char* result = pd_reserve_memory(bytes, addr, alignment_hint);
+  if (result != NULL && MemTracker::is_on()) {
+    MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
+  }
+
+  return result;
+}
+char* os::attempt_reserve_memory_at(size_t bytes, char* addr) {
+  char* result = pd_attempt_reserve_memory_at(bytes, addr);
+  if (result != NULL && MemTracker::is_on()) {
+    MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
+  }
+  return result;
+}
+
+void os::split_reserved_memory(char *base, size_t size,
+                                 size_t split, bool realloc) {
+  pd_split_reserved_memory(base, size, split, realloc);
+}
+
+bool os::commit_memory(char* addr, size_t bytes, bool executable) {
+  bool res = pd_commit_memory(addr, bytes, executable);
+  if (res && MemTracker::is_on()) {
+    MemTracker::record_virtual_memory_commit((address)addr, bytes, CALLER_PC);
+  }
+  return res;
+}
+
+bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
+                              bool executable) {
+  bool res = os::pd_commit_memory(addr, size, alignment_hint, executable);
+  if (res && MemTracker::is_on()) {
+    MemTracker::record_virtual_memory_commit((address)addr, size, CALLER_PC);
+  }
+  return res;
+}
+
+bool os::uncommit_memory(char* addr, size_t bytes) {
+  bool res = pd_uncommit_memory(addr, bytes);
+  if (res) {
+    MemTracker::record_virtual_memory_uncommit((address)addr, bytes);
+  }
+  return res;
+}
+
+bool os::release_memory(char* addr, size_t bytes) {
+  bool res = pd_release_memory(addr, bytes);
+  if (res) {
+    MemTracker::record_virtual_memory_release((address)addr, bytes);
+  }
+  return res;
+}
+
+
+char* os::map_memory(int fd, const char* file_name, size_t file_offset,
+                           char *addr, size_t bytes, bool read_only,
+                           bool allow_exec) {
+  char* result = pd_map_memory(fd, file_name, file_offset, addr, bytes, read_only, allow_exec);
+  if (result != NULL && MemTracker::is_on()) {
+    MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
+  }
+  return result;
+}
+
+char* os::remap_memory(int fd, const char* file_name, size_t file_offset,
+                             char *addr, size_t bytes, bool read_only,
+                             bool allow_exec) {
+  return pd_remap_memory(fd, file_name, file_offset, addr, bytes,
+                    read_only, allow_exec);
+}
+
+bool os::unmap_memory(char *addr, size_t bytes) {
+  bool result = pd_unmap_memory(addr, bytes);
+  if (result) {
+    MemTracker::record_virtual_memory_release((address)addr, bytes);
+  }
+  return result;
+}
+
+void os::free_memory(char *addr, size_t bytes, size_t alignment_hint) {
+  pd_free_memory(addr, bytes, alignment_hint);
+}
+
+void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
+  pd_realign_memory(addr, bytes, alignment_hint);
+}
+