Mercurial > hg > truffle
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 } |