2522 address addr = (address) exceptionRecord->ExceptionInformation[1]; |
2522 address addr = (address) exceptionRecord->ExceptionInformation[1]; |
2523 if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() ) { |
2523 if (addr > thread->stack_yellow_zone_base() && addr < thread->stack_base() ) { |
2524 addr = (address)((uintptr_t)addr & |
2524 addr = (address)((uintptr_t)addr & |
2525 (~((uintptr_t)os::vm_page_size() - (uintptr_t)1))); |
2525 (~((uintptr_t)os::vm_page_size() - (uintptr_t)1))); |
2526 os::commit_memory((char *)addr, thread->stack_base() - addr, |
2526 os::commit_memory((char *)addr, thread->stack_base() - addr, |
2527 false ); |
2527 !ExecMem); |
2528 return EXCEPTION_CONTINUE_EXECUTION; |
2528 return EXCEPTION_CONTINUE_EXECUTION; |
2529 } |
2529 } |
2530 else |
2530 else |
2531 #endif |
2531 #endif |
2532 { |
2532 { |
3170 } |
3170 } |
3171 |
3171 |
3172 void os::print_statistics() { |
3172 void os::print_statistics() { |
3173 } |
3173 } |
3174 |
3174 |
|
3175 static void warn_fail_commit_memory(char* addr, size_t bytes, bool exec) { |
|
3176 int err = os::get_last_error(); |
|
3177 char buf[256]; |
|
3178 size_t buf_len = os::lasterror(buf, sizeof(buf)); |
|
3179 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT |
|
3180 ", %d) failed; error='%s' (DOS error/errno=%d)", addr, bytes, |
|
3181 exec, buf_len != 0 ? buf : "<no_error_string>", err); |
|
3182 } |
|
3183 |
3175 bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) { |
3184 bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) { |
3176 if (bytes == 0) { |
3185 if (bytes == 0) { |
3177 // Don't bother the OS with noops. |
3186 // Don't bother the OS with noops. |
3178 return true; |
3187 return true; |
3179 } |
3188 } |
3184 |
3193 |
3185 // unless we have NUMAInterleaving enabled, the range of a commit |
3194 // unless we have NUMAInterleaving enabled, the range of a commit |
3186 // is always within a reserve covered by a single VirtualAlloc |
3195 // is always within a reserve covered by a single VirtualAlloc |
3187 // in that case we can just do a single commit for the requested size |
3196 // in that case we can just do a single commit for the requested size |
3188 if (!UseNUMAInterleaving) { |
3197 if (!UseNUMAInterleaving) { |
3189 if (VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) == NULL) return false; |
3198 if (VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) == NULL) { |
|
3199 NOT_PRODUCT(warn_fail_commit_memory(addr, bytes, exec);) |
|
3200 return false; |
|
3201 } |
3190 if (exec) { |
3202 if (exec) { |
3191 DWORD oldprot; |
3203 DWORD oldprot; |
3192 // Windows doc says to use VirtualProtect to get execute permissions |
3204 // Windows doc says to use VirtualProtect to get execute permissions |
3193 if (!VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot)) return false; |
3205 if (!VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot)) { |
|
3206 NOT_PRODUCT(warn_fail_commit_memory(addr, bytes, exec);) |
|
3207 return false; |
|
3208 } |
3194 } |
3209 } |
3195 return true; |
3210 return true; |
3196 } else { |
3211 } else { |
3197 |
3212 |
3198 // when NUMAInterleaving is enabled, the commit might cover a range that |
3213 // when NUMAInterleaving is enabled, the commit might cover a range that |
3203 char * next_alloc_addr = addr; |
3218 char * next_alloc_addr = addr; |
3204 while (bytes_remaining > 0) { |
3219 while (bytes_remaining > 0) { |
3205 MEMORY_BASIC_INFORMATION alloc_info; |
3220 MEMORY_BASIC_INFORMATION alloc_info; |
3206 VirtualQuery(next_alloc_addr, &alloc_info, sizeof(alloc_info)); |
3221 VirtualQuery(next_alloc_addr, &alloc_info, sizeof(alloc_info)); |
3207 size_t bytes_to_rq = MIN2(bytes_remaining, (size_t)alloc_info.RegionSize); |
3222 size_t bytes_to_rq = MIN2(bytes_remaining, (size_t)alloc_info.RegionSize); |
3208 if (VirtualAlloc(next_alloc_addr, bytes_to_rq, MEM_COMMIT, PAGE_READWRITE) == NULL) |
3223 if (VirtualAlloc(next_alloc_addr, bytes_to_rq, MEM_COMMIT, |
|
3224 PAGE_READWRITE) == NULL) { |
|
3225 NOT_PRODUCT(warn_fail_commit_memory(next_alloc_addr, bytes_to_rq, |
|
3226 exec);) |
3209 return false; |
3227 return false; |
|
3228 } |
3210 if (exec) { |
3229 if (exec) { |
3211 DWORD oldprot; |
3230 DWORD oldprot; |
3212 if (!VirtualProtect(next_alloc_addr, bytes_to_rq, PAGE_EXECUTE_READWRITE, &oldprot)) |
3231 if (!VirtualProtect(next_alloc_addr, bytes_to_rq, |
|
3232 PAGE_EXECUTE_READWRITE, &oldprot)) { |
|
3233 NOT_PRODUCT(warn_fail_commit_memory(next_alloc_addr, bytes_to_rq, |
|
3234 exec);) |
3213 return false; |
3235 return false; |
|
3236 } |
3214 } |
3237 } |
3215 bytes_remaining -= bytes_to_rq; |
3238 bytes_remaining -= bytes_to_rq; |
3216 next_alloc_addr += bytes_to_rq; |
3239 next_alloc_addr += bytes_to_rq; |
3217 } |
3240 } |
3218 } |
3241 } |
3220 return true; |
3243 return true; |
3221 } |
3244 } |
3222 |
3245 |
3223 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, |
3246 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, |
3224 bool exec) { |
3247 bool exec) { |
3225 return commit_memory(addr, size, exec); |
3248 // alignment_hint is ignored on this OS |
|
3249 return pd_commit_memory(addr, size, exec); |
|
3250 } |
|
3251 |
|
3252 void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec, |
|
3253 const char* mesg) { |
|
3254 assert(mesg != NULL, "mesg must be specified"); |
|
3255 if (!pd_commit_memory(addr, size, exec)) { |
|
3256 warn_fail_commit_memory(addr, size, exec); |
|
3257 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg); |
|
3258 } |
|
3259 } |
|
3260 |
|
3261 void os::pd_commit_memory_or_exit(char* addr, size_t size, |
|
3262 size_t alignment_hint, bool exec, |
|
3263 const char* mesg) { |
|
3264 // alignment_hint is ignored on this OS |
|
3265 pd_commit_memory_or_exit(addr, size, exec, mesg); |
3226 } |
3266 } |
3227 |
3267 |
3228 bool os::pd_uncommit_memory(char* addr, size_t bytes) { |
3268 bool os::pd_uncommit_memory(char* addr, size_t bytes) { |
3229 if (bytes == 0) { |
3269 if (bytes == 0) { |
3230 // Don't bother the OS with noops. |
3270 // Don't bother the OS with noops. |
3238 bool os::pd_release_memory(char* addr, size_t bytes) { |
3278 bool os::pd_release_memory(char* addr, size_t bytes) { |
3239 return VirtualFree(addr, 0, MEM_RELEASE) != 0; |
3279 return VirtualFree(addr, 0, MEM_RELEASE) != 0; |
3240 } |
3280 } |
3241 |
3281 |
3242 bool os::pd_create_stack_guard_pages(char* addr, size_t size) { |
3282 bool os::pd_create_stack_guard_pages(char* addr, size_t size) { |
3243 return os::commit_memory(addr, size); |
3283 return os::commit_memory(addr, size, !ExecMem); |
3244 } |
3284 } |
3245 |
3285 |
3246 bool os::remove_stack_guard_pages(char* addr, size_t size) { |
3286 bool os::remove_stack_guard_pages(char* addr, size_t size) { |
3247 return os::uncommit_memory(addr, size); |
3287 return os::uncommit_memory(addr, size); |
3248 } |
3288 } |
3262 |
3302 |
3263 DWORD old_status; |
3303 DWORD old_status; |
3264 |
3304 |
3265 // Strange enough, but on Win32 one can change protection only for committed |
3305 // Strange enough, but on Win32 one can change protection only for committed |
3266 // memory, not a big deal anyway, as bytes less or equal than 64K |
3306 // memory, not a big deal anyway, as bytes less or equal than 64K |
3267 if (!is_committed && !commit_memory(addr, bytes, prot == MEM_PROT_RWX)) { |
3307 if (!is_committed) { |
3268 fatal("cannot commit protection page"); |
3308 commit_memory_or_exit(addr, bytes, prot == MEM_PROT_RWX, |
|
3309 "cannot commit protection page"); |
3269 } |
3310 } |
3270 // One cannot use os::guard_memory() here, as on Win32 guard page |
3311 // One cannot use os::guard_memory() here, as on Win32 guard page |
3271 // have different (one-shot) semantics, from MSDN on PAGE_GUARD: |
3312 // have different (one-shot) semantics, from MSDN on PAGE_GUARD: |
3272 // |
3313 // |
3273 // Pages in the region become guard pages. Any attempt to access a guard page |
3314 // Pages in the region become guard pages. Any attempt to access a guard page |