Mercurial > hg > truffle
comparison src/os/windows/vm/os_windows.cpp @ 10986:1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
Summary: Fixed NMT race condition for realloc, uncommit and release
Reviewed-by: coleenp, ccheung
author | zgu |
---|---|
date | Tue, 18 Jun 2013 08:44:08 -0400 |
parents | a837fa3d3f86 |
children | 59b052799158 980532a806a5 |
comparison
equal
deleted
inserted
replaced
10984:cd2118b62475 | 10986:1f4355cee9a2 |
---|---|
2873 size_of_reserve, // size of Reserve | 2873 size_of_reserve, // size of Reserve |
2874 MEM_RESERVE, | 2874 MEM_RESERVE, |
2875 PAGE_READWRITE); | 2875 PAGE_READWRITE); |
2876 // If reservation failed, return NULL | 2876 // If reservation failed, return NULL |
2877 if (p_buf == NULL) return NULL; | 2877 if (p_buf == NULL) return NULL; |
2878 MemTracker::record_virtual_memory_reserve((address)p_buf, size_of_reserve, CALLER_PC); | 2878 MemTracker::record_virtual_memory_reserve((address)p_buf, size_of_reserve, mtNone, CALLER_PC); |
2879 os::release_memory(p_buf, bytes + chunk_size); | 2879 os::release_memory(p_buf, bytes + chunk_size); |
2880 | 2880 |
2881 // we still need to round up to a page boundary (in case we are using large pages) | 2881 // we still need to round up to a page boundary (in case we are using large pages) |
2882 // but not to a chunk boundary (in case InterleavingGranularity doesn't align with page size) | 2882 // but not to a chunk boundary (in case InterleavingGranularity doesn't align with page size) |
2883 // instead we handle this in the bytes_to_rq computation below | 2883 // instead we handle this in the bytes_to_rq computation below |
2939 size_t bytes_to_release = bytes - bytes_remaining; | 2939 size_t bytes_to_release = bytes - bytes_remaining; |
2940 // NMT has yet to record any individual blocks, so it | 2940 // NMT has yet to record any individual blocks, so it |
2941 // need to create a dummy 'reserve' record to match | 2941 // need to create a dummy 'reserve' record to match |
2942 // the release. | 2942 // the release. |
2943 MemTracker::record_virtual_memory_reserve((address)p_buf, | 2943 MemTracker::record_virtual_memory_reserve((address)p_buf, |
2944 bytes_to_release, CALLER_PC); | 2944 bytes_to_release, mtNone, CALLER_PC); |
2945 os::release_memory(p_buf, bytes_to_release); | 2945 os::release_memory(p_buf, bytes_to_release); |
2946 } | 2946 } |
2947 #ifdef ASSERT | 2947 #ifdef ASSERT |
2948 if (should_inject_error) { | 2948 if (should_inject_error) { |
2949 if (TracePageSizes && Verbose) { | 2949 if (TracePageSizes && Verbose) { |
2959 count++; | 2959 count++; |
2960 } | 2960 } |
2961 // Although the memory is allocated individually, it is returned as one. | 2961 // Although the memory is allocated individually, it is returned as one. |
2962 // NMT records it as one block. | 2962 // NMT records it as one block. |
2963 address pc = CALLER_PC; | 2963 address pc = CALLER_PC; |
2964 MemTracker::record_virtual_memory_reserve((address)p_buf, bytes, pc); | |
2965 if ((flags & MEM_COMMIT) != 0) { | 2964 if ((flags & MEM_COMMIT) != 0) { |
2966 MemTracker::record_virtual_memory_commit((address)p_buf, bytes, pc); | 2965 MemTracker::record_virtual_memory_reserve_and_commit((address)p_buf, bytes, mtNone, pc); |
2966 } else { | |
2967 MemTracker::record_virtual_memory_reserve((address)p_buf, bytes, mtNone, pc); | |
2967 } | 2968 } |
2968 | 2969 |
2969 // made it this far, success | 2970 // made it this far, success |
2970 return p_buf; | 2971 return p_buf; |
2971 } | 2972 } |
3152 // normal policy just allocate it all at once | 3153 // normal policy just allocate it all at once |
3153 DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES; | 3154 DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES; |
3154 char * res = (char *)VirtualAlloc(NULL, bytes, flag, prot); | 3155 char * res = (char *)VirtualAlloc(NULL, bytes, flag, prot); |
3155 if (res != NULL) { | 3156 if (res != NULL) { |
3156 address pc = CALLER_PC; | 3157 address pc = CALLER_PC; |
3157 MemTracker::record_virtual_memory_reserve((address)res, bytes, pc); | 3158 MemTracker::record_virtual_memory_reserve_and_commit((address)res, bytes, mtNone, pc); |
3158 MemTracker::record_virtual_memory_commit((address)res, bytes, pc); | |
3159 } | 3159 } |
3160 | 3160 |
3161 return res; | 3161 return res; |
3162 } | 3162 } |
3163 } | 3163 } |
3164 | 3164 |
3165 bool os::release_memory_special(char* base, size_t bytes) { | 3165 bool os::release_memory_special(char* base, size_t bytes) { |
3166 assert(base != NULL, "Sanity check"); | 3166 assert(base != NULL, "Sanity check"); |
3167 // Memory allocated via reserve_memory_special() is committed | |
3168 MemTracker::record_virtual_memory_uncommit((address)base, bytes); | |
3169 return release_memory(base, bytes); | 3167 return release_memory(base, bytes); |
3170 } | 3168 } |
3171 | 3169 |
3172 void os::print_statistics() { | 3170 void os::print_statistics() { |
3173 } | 3171 } |