comparison src/os/windows/vm/os_windows.cpp @ 8711:6b803ba47588

8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option Summary: Corrected virtual memory recording and tagging code when large pages are used Reviewed-by: coleenp, ccheung
author zgu
date Thu, 07 Mar 2013 14:06:44 -0500
parents 7adae9244bc8
children 754c24457b20 53028d751155 17bf4d428955
comparison
equal deleted inserted replaced
8710:9058789475af 8711:6b803ba47588
58 #include "runtime/stubRoutines.hpp" 58 #include "runtime/stubRoutines.hpp"
59 #include "runtime/thread.inline.hpp" 59 #include "runtime/thread.inline.hpp"
60 #include "runtime/threadCritical.hpp" 60 #include "runtime/threadCritical.hpp"
61 #include "runtime/timer.hpp" 61 #include "runtime/timer.hpp"
62 #include "services/attachListener.hpp" 62 #include "services/attachListener.hpp"
63 #include "services/memTracker.hpp"
63 #include "services/runtimeService.hpp" 64 #include "services/runtimeService.hpp"
64 #include "utilities/decoder.hpp" 65 #include "utilities/decoder.hpp"
65 #include "utilities/defaultStream.hpp" 66 #include "utilities/defaultStream.hpp"
66 #include "utilities/events.hpp" 67 #include "utilities/events.hpp"
67 #include "utilities/growableArray.hpp" 68 #include "utilities/growableArray.hpp"
2834 size_of_reserve, // size of Reserve 2835 size_of_reserve, // size of Reserve
2835 MEM_RESERVE, 2836 MEM_RESERVE,
2836 PAGE_READWRITE); 2837 PAGE_READWRITE);
2837 // If reservation failed, return NULL 2838 // If reservation failed, return NULL
2838 if (p_buf == NULL) return NULL; 2839 if (p_buf == NULL) return NULL;
2839 2840 MemTracker::record_virtual_memory_reserve((address)p_buf, size_of_reserve, CALLER_PC);
2840 os::release_memory(p_buf, bytes + chunk_size); 2841 os::release_memory(p_buf, bytes + chunk_size);
2841 2842
2842 // we still need to round up to a page boundary (in case we are using large pages) 2843 // we still need to round up to a page boundary (in case we are using large pages)
2843 // but not to a chunk boundary (in case InterleavingGranularity doesn't align with page size) 2844 // but not to a chunk boundary (in case InterleavingGranularity doesn't align with page size)
2844 // instead we handle this in the bytes_to_rq computation below 2845 // instead we handle this in the bytes_to_rq computation below
2896 if (p_new == NULL) { 2897 if (p_new == NULL) {
2897 // Free any allocated pages 2898 // Free any allocated pages
2898 if (next_alloc_addr > p_buf) { 2899 if (next_alloc_addr > p_buf) {
2899 // Some memory was committed so release it. 2900 // Some memory was committed so release it.
2900 size_t bytes_to_release = bytes - bytes_remaining; 2901 size_t bytes_to_release = bytes - bytes_remaining;
2902 // NMT has yet to record any individual blocks, so it
2903 // need to create a dummy 'reserve' record to match
2904 // the release.
2905 MemTracker::record_virtual_memory_reserve((address)p_buf,
2906 bytes_to_release, CALLER_PC);
2901 os::release_memory(p_buf, bytes_to_release); 2907 os::release_memory(p_buf, bytes_to_release);
2902 } 2908 }
2903 #ifdef ASSERT 2909 #ifdef ASSERT
2904 if (should_inject_error) { 2910 if (should_inject_error) {
2905 if (TracePageSizes && Verbose) { 2911 if (TracePageSizes && Verbose) {
2907 } 2913 }
2908 } 2914 }
2909 #endif 2915 #endif
2910 return NULL; 2916 return NULL;
2911 } 2917 }
2918
2912 bytes_remaining -= bytes_to_rq; 2919 bytes_remaining -= bytes_to_rq;
2913 next_alloc_addr += bytes_to_rq; 2920 next_alloc_addr += bytes_to_rq;
2914 count++; 2921 count++;
2915 } 2922 }
2923 // Although the memory is allocated individually, it is returned as one.
2924 // NMT records it as one block.
2925 address pc = CALLER_PC;
2926 MemTracker::record_virtual_memory_reserve((address)p_buf, bytes, pc);
2927 if ((flags & MEM_COMMIT) != 0) {
2928 MemTracker::record_virtual_memory_commit((address)p_buf, bytes, pc);
2929 }
2930
2916 // made it this far, success 2931 // made it this far, success
2917 return p_buf; 2932 return p_buf;
2918 } 2933 }
2919 2934
2920 2935
3097 3112
3098 } else { 3113 } else {
3099 // normal policy just allocate it all at once 3114 // normal policy just allocate it all at once
3100 DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES; 3115 DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
3101 char * res = (char *)VirtualAlloc(NULL, bytes, flag, prot); 3116 char * res = (char *)VirtualAlloc(NULL, bytes, flag, prot);
3117 if (res != NULL) {
3118 address pc = CALLER_PC;
3119 MemTracker::record_virtual_memory_reserve((address)res, bytes, pc);
3120 MemTracker::record_virtual_memory_commit((address)res, bytes, pc);
3121 }
3122
3102 return res; 3123 return res;
3103 } 3124 }
3104 } 3125 }
3105 3126
3106 bool os::release_memory_special(char* base, size_t bytes) { 3127 bool os::release_memory_special(char* base, size_t bytes) {
3128 assert(base != NULL, "Sanity check");
3129 // Memory allocated via reserve_memory_special() is committed
3130 MemTracker::record_virtual_memory_uncommit((address)base, bytes);
3107 return release_memory(base, bytes); 3131 return release_memory(base, bytes);
3108 } 3132 }
3109 3133
3110 void os::print_statistics() { 3134 void os::print_statistics() {
3111 } 3135 }