hotspot/src/os/windows/vm/os_windows.cpp
changeset 13195 be27e1b6a4b9
parent 12940 6882e094a6b5
child 13932 b8d718f01df4
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jun 27 15:23:36 2012 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Thu Jun 28 17:03:16 2012 -0400
@@ -96,7 +96,6 @@
 #include <io.h>
 #include <process.h>              // For _beginthreadex(), _endthreadex()
 #include <imagehlp.h>             // For os::dll_address_to_function_name
-
 /* for enumerating dll libraries */
 #include <vdmdbg.h>
 
@@ -214,13 +213,13 @@
           }
       }
 
-      home_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + 1);
+      home_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + 1, mtInternal);
       if (home_path == NULL)
           return;
       strcpy(home_path, home_dir);
       Arguments::set_java_home(home_path);
 
-      dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1);
+      dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1, mtInternal);
       if (dll_path == NULL)
           return;
       strcpy(dll_path, home_dir);
@@ -251,7 +250,7 @@
     char *path_str = ::getenv("PATH");
 
     library_path = NEW_C_HEAP_ARRAY(char, MAX_PATH * 5 + sizeof(PACKAGE_DIR) +
-        sizeof(BIN_DIR) + (path_str ? strlen(path_str) : 0) + 10);
+        sizeof(BIN_DIR) + (path_str ? strlen(path_str) : 0) + 10, mtInternal);
 
     library_path[0] = '\0';
 
@@ -280,7 +279,7 @@
     strcat(library_path, ";.");
 
     Arguments::set_library_path(library_path);
-    FREE_C_HEAP_ARRAY(char, library_path);
+    FREE_C_HEAP_ARRAY(char, library_path, mtInternal);
   }
 
   /* Default extensions directory */
@@ -300,7 +299,7 @@
   {
     #define ENDORSED_DIR "\\lib\\endorsed"
     size_t len = strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR);
-    char * buf = NEW_C_HEAP_ARRAY(char, len);
+    char * buf = NEW_C_HEAP_ARRAY(char, len, mtInternal);
     sprintf(buf, "%s%s", Arguments::get_java_home(), ENDORSED_DIR);
     Arguments::set_endorsed_dirs(buf);
     #undef ENDORSED_DIR
@@ -324,6 +323,23 @@
   os::breakpoint();
 }
 
+/*
+ * RtlCaptureStackBackTrace Windows API may not exist prior to Windows XP.
+ * So far, this method is only used by Native Memory Tracking, which is
+ * only supported on Windows XP or later.
+ */
+address os::get_caller_pc(int n) {
+#ifdef _NMT_NOINLINE_
+  n ++;
+#endif
+  address pc;
+  if (os::Kernel32Dll::RtlCaptureStackBackTrace(n + 1, 1, (PVOID*)&pc, NULL) == 1) {
+    return pc;
+  }
+  return NULL;
+}
+
+
 // os::current_stack_base()
 //
 //   Returns the base of the stack, which is the stack's
@@ -1014,7 +1030,7 @@
 os::opendir(const char *dirname)
 {
     assert(dirname != NULL, "just checking");   // hotspot change
-    DIR *dirp = (DIR *)malloc(sizeof(DIR));
+    DIR *dirp = (DIR *)malloc(sizeof(DIR), mtInternal);
     DWORD fattr;                                // hotspot change
     char alt_dirname[4] = { 0, 0, 0, 0 };
 
@@ -1036,9 +1052,9 @@
         dirname = alt_dirname;
     }
 
-    dirp->path = (char *)malloc(strlen(dirname) + 5);
+    dirp->path = (char *)malloc(strlen(dirname) + 5, mtInternal);
     if (dirp->path == 0) {
-        free(dirp);
+        free(dirp, mtInternal);
         errno = ENOMEM;
         return 0;
     }
@@ -1046,13 +1062,13 @@
 
     fattr = GetFileAttributes(dirp->path);
     if (fattr == 0xffffffff) {
-        free(dirp->path);
-        free(dirp);
+        free(dirp->path, mtInternal);
+        free(dirp, mtInternal);
         errno = ENOENT;
         return 0;
     } else if ((fattr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
-        free(dirp->path);
-        free(dirp);
+        free(dirp->path, mtInternal);
+        free(dirp, mtInternal);
         errno = ENOTDIR;
         return 0;
     }
@@ -1070,8 +1086,8 @@
     dirp->handle = FindFirstFile(dirp->path, &dirp->find_data);
     if (dirp->handle == INVALID_HANDLE_VALUE) {
         if (GetLastError() != ERROR_FILE_NOT_FOUND) {
-            free(dirp->path);
-            free(dirp);
+            free(dirp->path, mtInternal);
+            free(dirp, mtInternal);
             errno = EACCES;
             return 0;
         }
@@ -1114,8 +1130,8 @@
         }
         dirp->handle = INVALID_HANDLE_VALUE;
     }
-    free(dirp->path);
-    free(dirp);
+    free(dirp->path, mtInternal);
+    free(dirp, mtInternal);
     return 0;
 }
 
@@ -1176,11 +1192,11 @@
     // release the storage
     for (int i = 0 ; i < n ; i++) {
       if (pelements[i] != NULL) {
-        FREE_C_HEAP_ARRAY(char, pelements[i]);
+        FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
       }
     }
     if (pelements != NULL) {
-      FREE_C_HEAP_ARRAY(char*, pelements);
+      FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
     }
   } else {
     jio_snprintf(buffer, buflen, "%s\\%s.dll", pname, fname);
@@ -2637,7 +2653,7 @@
 
   void free_node_list() {
     if (_numa_used_node_list != NULL) {
-      FREE_C_HEAP_ARRAY(int, _numa_used_node_list);
+      FREE_C_HEAP_ARRAY(int, _numa_used_node_list, mtInternal);
     }
   }
 
@@ -2659,7 +2675,7 @@
     ULONG highest_node_number;
     if (!os::Kernel32Dll::GetNumaHighestNodeNumber(&highest_node_number)) return false;
     free_node_list();
-    _numa_used_node_list = NEW_C_HEAP_ARRAY(int, highest_node_number + 1);
+    _numa_used_node_list = NEW_C_HEAP_ARRAY(int, highest_node_number + 1, mtInternal);
     for (unsigned int i = 0; i <= highest_node_number; i++) {
       ULONGLONG proc_mask_numa_node;
       if (!os::Kernel32Dll::GetNumaNodeProcessorMask(i, &proc_mask_numa_node)) return false;
@@ -2918,7 +2934,7 @@
 // On win32, one cannot release just a part of reserved memory, it's an
 // all or nothing deal.  When we split a reservation, we must break the
 // reservation into two reservations.
-void os::split_reserved_memory(char *base, size_t size, size_t split,
+void os::pd_split_reserved_memory(char *base, size_t size, size_t split,
                               bool realloc) {
   if (size > 0) {
     release_memory(base, size);
@@ -2931,7 +2947,7 @@
   }
 }
 
-char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
+char* os::pd_reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
   assert((size_t)addr % os::vm_allocation_granularity() == 0,
          "reserve alignment");
   assert(bytes % os::vm_allocation_granularity() == 0, "reserve block size");
@@ -2964,7 +2980,7 @@
 
 // Reserve memory at an arbitrary address, only if that area is
 // available (and not reserved for something else).
-char* os::attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
+char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
   // Windows os::reserve_memory() fails of the requested address range is
   // not avilable.
   return reserve_memory(bytes, requested_addr);
@@ -3027,7 +3043,7 @@
 void os::print_statistics() {
 }
 
-bool os::commit_memory(char* addr, size_t bytes, bool exec) {
+bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
   if (bytes == 0) {
     // Don't bother the OS with noops.
     return true;
@@ -3075,26 +3091,26 @@
   return true;
 }
 
-bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
+bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
                        bool exec) {
   return commit_memory(addr, size, exec);
 }
 
-bool os::uncommit_memory(char* addr, size_t bytes) {
+bool os::pd_uncommit_memory(char* addr, size_t bytes) {
   if (bytes == 0) {
     // Don't bother the OS with noops.
     return true;
   }
   assert((size_t) addr % os::vm_page_size() == 0, "uncommit on page boundaries");
   assert(bytes % os::vm_page_size() == 0, "uncommit in page-sized chunks");
-  return VirtualFree(addr, bytes, MEM_DECOMMIT) != 0;
-}
-
-bool os::release_memory(char* addr, size_t bytes) {
+  return (VirtualFree(addr, bytes, MEM_DECOMMIT) != 0);
+}
+
+bool os::pd_release_memory(char* addr, size_t bytes) {
   return VirtualFree(addr, 0, MEM_RELEASE) != 0;
 }
 
-bool os::create_stack_guard_pages(char* addr, size_t size) {
+bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
   return os::commit_memory(addr, size);
 }
 
@@ -3141,8 +3157,8 @@
   return VirtualProtect(addr, bytes, PAGE_READWRITE, &old_status) != 0;
 }
 
-void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }
-void os::free_memory(char *addr, size_t bytes, size_t alignment_hint)    { }
+void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }
+void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) { }
 void os::numa_make_global(char *addr, size_t bytes)    { }
 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint)    { }
 bool os::numa_topology_changed()                       { return false; }
@@ -4276,14 +4292,14 @@
     numEvents = MAX_INPUT_EVENTS;
   }
 
-  lpBuffer = (INPUT_RECORD *)os::malloc(numEvents * sizeof(INPUT_RECORD));
+  lpBuffer = (INPUT_RECORD *)os::malloc(numEvents * sizeof(INPUT_RECORD), mtInternal);
   if (lpBuffer == NULL) {
     return FALSE;
   }
 
   error = ::PeekConsoleInput(han, lpBuffer, numEvents, &numEventsRead);
   if (error == 0) {
-    os::free(lpBuffer);
+    os::free(lpBuffer, mtInternal);
     return FALSE;
   }
 
@@ -4304,7 +4320,7 @@
   }
 
   if(lpBuffer != NULL) {
-    os::free(lpBuffer);
+    os::free(lpBuffer, mtInternal);
   }
 
   *pbytes = (long) actualLength;
@@ -4312,7 +4328,7 @@
 }
 
 // Map a block of memory.
-char* os::map_memory(int fd, const char* file_name, size_t file_offset,
+char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
                      char *addr, size_t bytes, bool read_only,
                      bool allow_exec) {
   HANDLE hFile;
@@ -4432,7 +4448,7 @@
 
 
 // Remap a block of memory.
-char* os::remap_memory(int fd, const char* file_name, size_t file_offset,
+char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,
                        char *addr, size_t bytes, bool read_only,
                        bool allow_exec) {
   // This OS does not allow existing memory maps to be remapped so we
@@ -4445,15 +4461,15 @@
   // call above and the map_memory() call below where a thread in native
   // code may be able to access an address that is no longer mapped.
 
-  return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,
-                        allow_exec);
+  return os::map_memory(fd, file_name, file_offset, addr, bytes,
+           read_only, allow_exec);
 }
 
 
 // Unmap a block of memory.
 // Returns true=success, otherwise false.
 
-bool os::unmap_memory(char* addr, size_t bytes) {
+bool os::pd_unmap_memory(char* addr, size_t bytes) {
   BOOL result = UnmapViewOfFile(addr);
   if (result == 0) {
     if (PrintMiscellaneous && Verbose) {
@@ -4931,11 +4947,15 @@
 typedef LPVOID (WINAPI *VirtualAllocExNuma_Fn) (HANDLE, LPVOID, SIZE_T, DWORD, DWORD, DWORD);
 typedef BOOL (WINAPI *GetNumaHighestNodeNumber_Fn) (PULONG);
 typedef BOOL (WINAPI *GetNumaNodeProcessorMask_Fn) (UCHAR, PULONGLONG);
+typedef USHORT (WINAPI* RtlCaptureStackBackTrace_Fn)(ULONG, ULONG, PVOID*, PULONG);
 
 GetLargePageMinimum_Fn      os::Kernel32Dll::_GetLargePageMinimum = NULL;
 VirtualAllocExNuma_Fn       os::Kernel32Dll::_VirtualAllocExNuma = NULL;
 GetNumaHighestNodeNumber_Fn os::Kernel32Dll::_GetNumaHighestNodeNumber = NULL;
 GetNumaNodeProcessorMask_Fn os::Kernel32Dll::_GetNumaNodeProcessorMask = NULL;
+RtlCaptureStackBackTrace_Fn os::Kernel32Dll::_RtlCaptureStackBackTrace = NULL;
+
+
 BOOL                        os::Kernel32Dll::initialized = FALSE;
 SIZE_T os::Kernel32Dll::GetLargePageMinimum() {
   assert(initialized && _GetLargePageMinimum != NULL,
@@ -4978,6 +4998,19 @@
   return _GetNumaNodeProcessorMask(node, proc_mask);
 }
 
+USHORT os::Kernel32Dll::RtlCaptureStackBackTrace(ULONG FrameToSkip,
+  ULONG FrameToCapture, PVOID* BackTrace, PULONG BackTraceHash) {
+    if (!initialized) {
+      initialize();
+    }
+
+    if (_RtlCaptureStackBackTrace != NULL) {
+      return _RtlCaptureStackBackTrace(FrameToSkip, FrameToCapture,
+        BackTrace, BackTraceHash);
+    } else {
+      return 0;
+    }
+}
 
 void os::Kernel32Dll::initializeCommon() {
   if (!initialized) {
@@ -4987,6 +5020,7 @@
     _VirtualAllocExNuma = (VirtualAllocExNuma_Fn)::GetProcAddress(handle, "VirtualAllocExNuma");
     _GetNumaHighestNodeNumber = (GetNumaHighestNodeNumber_Fn)::GetProcAddress(handle, "GetNumaHighestNodeNumber");
     _GetNumaNodeProcessorMask = (GetNumaNodeProcessorMask_Fn)::GetProcAddress(handle, "GetNumaNodeProcessorMask");
+    _RtlCaptureStackBackTrace = (RtlCaptureStackBackTrace_Fn)::GetProcAddress(handle, "RtlCaptureStackBackTrace");
     initialized = TRUE;
   }
 }
@@ -5101,7 +5135,6 @@
 Module32Next_Fn             os::Kernel32Dll::_Module32Next = NULL;
 GetNativeSystemInfo_Fn      os::Kernel32Dll::_GetNativeSystemInfo = NULL;
 
-
 void os::Kernel32Dll::initialize() {
   if (!initialized) {
     HMODULE handle = ::GetModuleHandle("Kernel32.dll");
@@ -5179,8 +5212,6 @@
   _GetNativeSystemInfo(lpSystemInfo);
 }
 
-
-
 // PSAPI API