hotspot/src/os/windows/vm/os_windows.cpp
changeset 18069 e6d4971c8650
parent 18025 b7bcf7497f93
child 18086 f44cf213a775
equal deleted inserted replaced
18025:b7bcf7497f93 18069:e6d4971c8650
  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