< prev index next >

src/os/windows/vm/os_windows.cpp

Print this page




3397     // Don't bother the OS with noops.
3398     return true;
3399   }
3400   assert((size_t) addr % os::vm_page_size() == 0, "uncommit on page boundaries");
3401   assert(bytes % os::vm_page_size() == 0, "uncommit in page-sized chunks");
3402   return (VirtualFree(addr, bytes, MEM_DECOMMIT) != 0);
3403 }
3404 
3405 bool os::pd_release_memory(char* addr, size_t bytes) {
3406   return VirtualFree(addr, 0, MEM_RELEASE) != 0;
3407 }
3408 
3409 bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
3410   return os::commit_memory(addr, size, !ExecMem);
3411 }
3412 
3413 bool os::remove_stack_guard_pages(char* addr, size_t size) {
3414   return os::uncommit_memory(addr, size);
3415 }
3416 






























3417 // Set protections specified
3418 bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
3419                         bool is_committed) {
3420   unsigned int p = 0;
3421   switch (prot) {
3422   case MEM_PROT_NONE: p = PAGE_NOACCESS; break;
3423   case MEM_PROT_READ: p = PAGE_READONLY; break;
3424   case MEM_PROT_RW:   p = PAGE_READWRITE; break;
3425   case MEM_PROT_RWX:  p = PAGE_EXECUTE_READWRITE; break;
3426   default:
3427     ShouldNotReachHere();
3428   }
3429 
3430   DWORD old_status;
3431 
3432   // Strange enough, but on Win32 one can change protection only for committed
3433   // memory, not a big deal anyway, as bytes less or equal than 64K
3434   if (!is_committed) {
3435     commit_memory_or_exit(addr, bytes, prot == MEM_PROT_RWX,
3436                           "cannot commit protection page");
3437   }
3438   // One cannot use os::guard_memory() here, as on Win32 guard page
3439   // have different (one-shot) semantics, from MSDN on PAGE_GUARD:
3440   //
3441   // Pages in the region become guard pages. Any attempt to access a guard page
3442   // causes the system to raise a STATUS_GUARD_PAGE exception and turn off
3443   // the guard page status. Guard pages thus act as a one-time access alarm.
3444   return VirtualProtect(addr, bytes, p, &old_status) != 0;











3445 }
3446 
3447 bool os::guard_memory(char* addr, size_t bytes) {
3448   DWORD old_status;
3449   return VirtualProtect(addr, bytes, PAGE_READWRITE | PAGE_GUARD, &old_status) != 0;
3450 }
3451 
3452 bool os::unguard_memory(char* addr, size_t bytes) {
3453   DWORD old_status;
3454   return VirtualProtect(addr, bytes, PAGE_READWRITE, &old_status) != 0;
3455 }
3456 
3457 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }
3458 void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) { }
3459 void os::numa_make_global(char *addr, size_t bytes)    { }
3460 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint)    { }
3461 bool os::numa_topology_changed()                       { return false; }
3462 size_t os::numa_get_groups_num()                       { return MAX2(numa_node_list_holder.get_count(), 1); }
3463 int os::numa_get_group_id()                            { return 0; }
3464 size_t os::numa_get_leaf_groups(int *ids, size_t size) {




3397     // Don't bother the OS with noops.
3398     return true;
3399   }
3400   assert((size_t) addr % os::vm_page_size() == 0, "uncommit on page boundaries");
3401   assert(bytes % os::vm_page_size() == 0, "uncommit in page-sized chunks");
3402   return (VirtualFree(addr, bytes, MEM_DECOMMIT) != 0);
3403 }
3404 
3405 bool os::pd_release_memory(char* addr, size_t bytes) {
3406   return VirtualFree(addr, 0, MEM_RELEASE) != 0;
3407 }
3408 
3409 bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
3410   return os::commit_memory(addr, size, !ExecMem);
3411 }
3412 
3413 bool os::remove_stack_guard_pages(char* addr, size_t size) {
3414   return os::uncommit_memory(addr, size);
3415 }
3416 
3417 static bool protect_pages_individually(char* addr, size_t bytes, unsigned int p, DWORD *old_status) {
3418   uint count = 0;
3419   bool ret = false;
3420   size_t bytes_remaining = bytes;
3421   char * next_protect_addr = addr;
3422 
3423   // Use VirtualQuery() to get the chunk size.
3424   while (bytes_remaining) {
3425     MEMORY_BASIC_INFORMATION alloc_info;
3426     ret = VirtualQuery(next_protect_addr, &alloc_info, sizeof(alloc_info)) != 0;
3427     if (!ret) {
3428       return false;
3429     }
3430 
3431     size_t bytes_to_protect = MIN2(bytes_remaining, (size_t)alloc_info.RegionSize);
3432     // We used different API at allocate_pages_individually() based on UseNUMAInterleaving,
3433     // but we don't distinguish here as both cases are protected by same API.
3434     ret = VirtualProtect(next_protect_addr, bytes_to_protect, p, old_status) != 0;
3435     assert(ret, "Failed protecting chunk #%u", count);
3436     if (!ret) {
3437       return false;
3438     }
3439 
3440     bytes_remaining -= bytes_to_protect;
3441     next_protect_addr += bytes_to_protect;
3442     count++;
3443   }
3444   return ret;
3445 }
3446 
3447 // Set protections specified
3448 bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
3449                         bool is_committed) {
3450   unsigned int p = 0;
3451   switch (prot) {
3452   case MEM_PROT_NONE: p = PAGE_NOACCESS; break;
3453   case MEM_PROT_READ: p = PAGE_READONLY; break;
3454   case MEM_PROT_RW:   p = PAGE_READWRITE; break;
3455   case MEM_PROT_RWX:  p = PAGE_EXECUTE_READWRITE; break;
3456   default:
3457     ShouldNotReachHere();
3458   }
3459 
3460   DWORD old_status;
3461 
3462   // Strange enough, but on Win32 one can change protection only for committed
3463   // memory, not a big deal anyway, as bytes less or equal than 64K
3464   if (!is_committed) {
3465     commit_memory_or_exit(addr, bytes, prot == MEM_PROT_RWX,
3466                           "cannot commit protection page");
3467   }
3468   // One cannot use os::guard_memory() here, as on Win32 guard page
3469   // have different (one-shot) semantics, from MSDN on PAGE_GUARD:
3470   //
3471   // Pages in the region become guard pages. Any attempt to access a guard page
3472   // causes the system to raise a STATUS_GUARD_PAGE exception and turn off
3473   // the guard page status. Guard pages thus act as a one-time access alarm.
3474   bool ret = protect_pages_individually(addr, bytes, p, &old_status);
3475 #ifdef ASSERT
3476   if (!ret) {
3477     int err = os::get_last_error();
3478     char buf[256];
3479     size_t buf_len = os::lasterror(buf, sizeof(buf));
3480     warning("INFO: os::protect_memory(" PTR_FORMAT ", " SIZE_FORMAT
3481           ") failed; error='%s' (DOS error/errno=%d)", addr, bytes,
3482           buf_len != 0 ? buf : "<no_error_string>", err);
3483   }
3484 #endif
3485   return ret;
3486 }
3487 
3488 bool os::guard_memory(char* addr, size_t bytes) {
3489   DWORD old_status;
3490   return VirtualProtect(addr, bytes, PAGE_READWRITE | PAGE_GUARD, &old_status) != 0;
3491 }
3492 
3493 bool os::unguard_memory(char* addr, size_t bytes) {
3494   DWORD old_status;
3495   return VirtualProtect(addr, bytes, PAGE_READWRITE, &old_status) != 0;
3496 }
3497 
3498 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }
3499 void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) { }
3500 void os::numa_make_global(char *addr, size_t bytes)    { }
3501 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint)    { }
3502 bool os::numa_topology_changed()                       { return false; }
3503 size_t os::numa_get_groups_num()                       { return MAX2(numa_node_list_holder.get_count(), 1); }
3504 int os::numa_get_group_id()                            { return 0; }
3505 size_t os::numa_get_leaf_groups(int *ids, size_t size) {


< prev index next >