3316 |
3316 |
3317 bool os::remove_stack_guard_pages(char* addr, size_t size) { |
3317 bool os::remove_stack_guard_pages(char* addr, size_t size) { |
3318 return os::uncommit_memory(addr, size); |
3318 return os::uncommit_memory(addr, size); |
3319 } |
3319 } |
3320 |
3320 |
|
3321 static bool protect_pages_individually(char* addr, size_t bytes, unsigned int p, DWORD *old_status) { |
|
3322 uint count = 0; |
|
3323 bool ret = false; |
|
3324 size_t bytes_remaining = bytes; |
|
3325 char * next_protect_addr = addr; |
|
3326 |
|
3327 // Use VirtualQuery() to get the chunk size. |
|
3328 while (bytes_remaining) { |
|
3329 MEMORY_BASIC_INFORMATION alloc_info; |
|
3330 if (VirtualQuery(next_protect_addr, &alloc_info, sizeof(alloc_info)) == 0) { |
|
3331 return false; |
|
3332 } |
|
3333 |
|
3334 size_t bytes_to_protect = MIN2(bytes_remaining, (size_t)alloc_info.RegionSize); |
|
3335 // We used different API at allocate_pages_individually() based on UseNUMAInterleaving, |
|
3336 // but we don't distinguish here as both cases are protected by same API. |
|
3337 ret = VirtualProtect(next_protect_addr, bytes_to_protect, p, old_status) != 0; |
|
3338 warning("Failed protecting pages individually for chunk #%u", count); |
|
3339 if (!ret) { |
|
3340 return false; |
|
3341 } |
|
3342 |
|
3343 bytes_remaining -= bytes_to_protect; |
|
3344 next_protect_addr += bytes_to_protect; |
|
3345 count++; |
|
3346 } |
|
3347 return ret; |
|
3348 } |
|
3349 |
3321 // Set protections specified |
3350 // Set protections specified |
3322 bool os::protect_memory(char* addr, size_t bytes, ProtType prot, |
3351 bool os::protect_memory(char* addr, size_t bytes, ProtType prot, |
3323 bool is_committed) { |
3352 bool is_committed) { |
3324 unsigned int p = 0; |
3353 unsigned int p = 0; |
3325 switch (prot) { |
3354 switch (prot) { |
3343 // have different (one-shot) semantics, from MSDN on PAGE_GUARD: |
3372 // have different (one-shot) semantics, from MSDN on PAGE_GUARD: |
3344 // |
3373 // |
3345 // Pages in the region become guard pages. Any attempt to access a guard page |
3374 // Pages in the region become guard pages. Any attempt to access a guard page |
3346 // causes the system to raise a STATUS_GUARD_PAGE exception and turn off |
3375 // causes the system to raise a STATUS_GUARD_PAGE exception and turn off |
3347 // the guard page status. Guard pages thus act as a one-time access alarm. |
3376 // the guard page status. Guard pages thus act as a one-time access alarm. |
3348 return VirtualProtect(addr, bytes, p, &old_status) != 0; |
3377 bool ret; |
|
3378 if (UseNUMAInterleaving) { |
|
3379 // If UseNUMAInterleaving is enabled, the pages may have been allocated a chunk at a time, |
|
3380 // so we must protect the chunks individually. |
|
3381 ret = protect_pages_individually(addr, bytes, p, &old_status); |
|
3382 } else { |
|
3383 ret = VirtualProtect(addr, bytes, p, &old_status) != 0; |
|
3384 } |
|
3385 #ifdef ASSERT |
|
3386 if (!ret) { |
|
3387 int err = os::get_last_error(); |
|
3388 char buf[256]; |
|
3389 size_t buf_len = os::lasterror(buf, sizeof(buf)); |
|
3390 warning("INFO: os::protect_memory(" PTR_FORMAT ", " SIZE_FORMAT |
|
3391 ") failed; error='%s' (DOS error/errno=%d)", addr, bytes, |
|
3392 buf_len != 0 ? buf : "<no_error_string>", err); |
|
3393 } |
|
3394 #endif |
|
3395 return ret; |
3349 } |
3396 } |
3350 |
3397 |
3351 bool os::guard_memory(char* addr, size_t bytes) { |
3398 bool os::guard_memory(char* addr, size_t bytes) { |
3352 DWORD old_status; |
3399 DWORD old_status; |
3353 return VirtualProtect(addr, bytes, PAGE_READWRITE | PAGE_GUARD, &old_status) != 0; |
3400 return VirtualProtect(addr, bytes, PAGE_READWRITE | PAGE_GUARD, &old_status) != 0; |