< prev index next >

src/os/windows/vm/os_windows.cpp

Print this page
rev 9751 : [mq]: webrev.00
rev 9752 : [mq]: webrev.01
rev 9753 : [mq]: webrev.02
rev 9754 : [mq]: webrev.03


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     if (VirtualQuery(next_protect_addr, &alloc_info, sizeof(alloc_info)) == 0) {
3427       return false;
3428     }
3429 
3430     size_t bytes_to_protect = MIN2(bytes_remaining, (size_t)alloc_info.RegionSize);
3431     // We used different API at allocate_pages_individually() based on UseNUMAInterleaving,
3432     // but we don't distinguish here as both cases are protected by same API.
3433     ret = VirtualProtect(next_protect_addr, bytes_to_protect, p, old_status) != 0;
3434     assert(ret, "Failed protecting chunk #%u", count);
3435     if (!ret) {
3436       return false;
3437     }
3438 
3439     bytes_remaining -= bytes_to_protect;
3440     next_protect_addr += bytes_to_protect;
3441     count++;
3442   }
3443   return ret;
3444 }
3445 
3446 // Set protections specified
3447 bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
3448                         bool is_committed) {
3449   unsigned int p = 0;
3450   switch (prot) {
3451   case MEM_PROT_NONE: p = PAGE_NOACCESS; break;
3452   case MEM_PROT_READ: p = PAGE_READONLY; break;
3453   case MEM_PROT_RW:   p = PAGE_READWRITE; break;
3454   case MEM_PROT_RWX:  p = PAGE_EXECUTE_READWRITE; break;
3455   default:
3456     ShouldNotReachHere();
3457   }
3458 
3459   DWORD old_status;
3460 
3461   // Strange enough, but on Win32 one can change protection only for committed
3462   // memory, not a big deal anyway, as bytes less or equal than 64K
3463   if (!is_committed) {
3464     commit_memory_or_exit(addr, bytes, prot == MEM_PROT_RWX,
3465                           "cannot commit protection page");
3466   }
3467   // One cannot use os::guard_memory() here, as on Win32 guard page
3468   // have different (one-shot) semantics, from MSDN on PAGE_GUARD:
3469   //
3470   // Pages in the region become guard pages. Any attempt to access a guard page
3471   // causes the system to raise a STATUS_GUARD_PAGE exception and turn off
3472   // the guard page status. Guard pages thus act as a one-time access alarm.
3473   bool ret;
3474   if (UseNUMAInterleaving) {
3475     // If UseNUMAInterleaving is enabled, the pages may have been allocated a chunk at a time,
3476     // so we must protect the chunks individually.
3477     ret = protect_pages_individually(addr, bytes, p, &old_status);
3478   } else {
3479     ret = VirtualProtect(addr, bytes, p, &old_status) != 0;
3480   }
3481 #ifdef ASSERT
3482   if (!ret) {
3483     int err = os::get_last_error();
3484     char buf[256];
3485     size_t buf_len = os::lasterror(buf, sizeof(buf));
3486     warning("INFO: os::protect_memory(" PTR_FORMAT ", " SIZE_FORMAT
3487           ") failed; error='%s' (DOS error/errno=%d)", addr, bytes,
3488           buf_len != 0 ? buf : "<no_error_string>", err);
3489   }
3490 #endif
3491   return ret;
3492 }
3493 
3494 bool os::guard_memory(char* addr, size_t bytes) {
3495   DWORD old_status;
3496   return VirtualProtect(addr, bytes, PAGE_READWRITE | PAGE_GUARD, &old_status) != 0;
3497 }
3498 
3499 bool os::unguard_memory(char* addr, size_t bytes) {
3500   DWORD old_status;
3501   return VirtualProtect(addr, bytes, PAGE_READWRITE, &old_status) != 0;
3502 }
3503 
3504 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }
3505 void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) { }
3506 void os::numa_make_global(char *addr, size_t bytes)    { }
3507 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint)    { }
3508 bool os::numa_topology_changed()                       { return false; }
3509 size_t os::numa_get_groups_num()                       { return MAX2(numa_node_list_holder.get_count(), 1); }
3510 int os::numa_get_group_id()                            { return 0; }
3511 size_t os::numa_get_leaf_groups(int *ids, size_t size) {


< prev index next >