< prev index next >

src/hotspot/os/windows/os_windows.cpp

Print this page




2865 #endif
2866     } else {
2867       WARN("Large page is not supported by the processor.");
2868     }
2869   } else {
2870     WARN("JVM cannot use large page memory because it does not have enough privilege to lock pages in memory.");
2871   }
2872 #undef WARN
2873 
2874   const size_t default_page_size = (size_t) vm_page_size();
2875   if (success && _large_page_size > default_page_size) {
2876     _page_sizes[0] = _large_page_size;
2877     _page_sizes[1] = default_page_size;
2878     _page_sizes[2] = 0;
2879   }
2880 
2881   cleanup_after_large_page_init();
2882   UseLargePages = success;
2883 }
2884 
































































2885 // On win32, one cannot release just a part of reserved memory, it's an
2886 // all or nothing deal.  When we split a reservation, we must break the
2887 // reservation into two reservations.
2888 void os::pd_split_reserved_memory(char *base, size_t size, size_t split,
2889                                   bool realloc) {
2890   if (size > 0) {
2891     release_memory(base, size);
2892     if (realloc) {
2893       reserve_memory(split, base);
2894     }
2895     if (size != split) {
2896       reserve_memory(size - split, base + split);
2897     }
2898   }
2899 }
2900 
2901 // Multiple threads can race in this code but it's not possible to unmap small sections of
2902 // virtual space to get requested alignment, like posix-like os's.
2903 // Windows prevents multiple thread from remapping over each other so this loop is thread-safe.
2904 char* os::reserve_memory_aligned(size_t size, size_t alignment) {
2905   assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
2906          "Alignment must be a multiple of allocation granularity (page size)");
2907   assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");
2908 
2909   size_t extra_size = size + alignment;
2910   assert(extra_size >= size, "overflow, size is too large to allow alignment");
2911 
2912   char* aligned_base = NULL;
2913 
2914   do {
2915     char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
2916     if (extra_base == NULL) {
2917       return NULL;
2918     }
2919     // Do manual alignment
2920     aligned_base = align_up(extra_base, alignment);
2921 



2922     os::release_memory(extra_base, extra_size);

2923 
2924     aligned_base = os::reserve_memory(size, aligned_base);
2925 
2926   } while (aligned_base == NULL);
2927 
2928   return aligned_base;
2929 }
2930 
2931 char* os::pd_reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
2932   assert((size_t)addr % os::vm_allocation_granularity() == 0,
2933          "reserve alignment");
2934   assert(bytes % os::vm_page_size() == 0, "reserve page size");
2935   char* res;
2936   // note that if UseLargePages is on, all the areas that require interleaving
2937   // will go thru reserve_memory_special rather than thru here.
2938   bool use_individual = (UseNUMAInterleaving && !UseLargePages);
2939   if (!use_individual) {
2940     res = (char*)VirtualAlloc(addr, bytes, MEM_RESERVE, PAGE_READWRITE);
2941   } else {
2942     elapsedTimer reserveTimer;
2943     if (Verbose && PrintMiscellaneous) reserveTimer.start();
2944     // in numa interleaving, we have to allocate pages individually


2948       warning("NUMA page allocation failed");
2949     }
2950     if (Verbose && PrintMiscellaneous) {
2951       reserveTimer.stop();
2952       tty->print_cr("reserve_memory of %Ix bytes took " JLONG_FORMAT " ms (" JLONG_FORMAT " ticks)", bytes,
2953                     reserveTimer.milliseconds(), reserveTimer.ticks());
2954     }
2955   }
2956   assert(res == NULL || addr == NULL || addr == res,
2957          "Unexpected address from reserve.");
2958 
2959   return res;
2960 }
2961 
2962 // Reserve memory at an arbitrary address, only if that area is
2963 // available (and not reserved for something else).
2964 char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
2965   // Windows os::reserve_memory() fails of the requested address range is
2966   // not avilable.
2967   return reserve_memory(bytes, requested_addr);





2968 }
2969 
2970 size_t os::large_page_size() {
2971   return _large_page_size;
2972 }
2973 
2974 bool os::can_commit_large_page_memory() {
2975   // Windows only uses large page memory when the entire region is reserved
2976   // and committed in a single VirtualAlloc() call. This may change in the
2977   // future, but with Windows 2003 it's not possible to commit on demand.
2978   return false;
2979 }
2980 
2981 bool os::can_execute_large_page_memory() {
2982   return true;
2983 }
2984 
2985 char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr,
2986                                  bool exec) {
2987   assert(UseLargePages, "only for large pages");




2865 #endif
2866     } else {
2867       WARN("Large page is not supported by the processor.");
2868     }
2869   } else {
2870     WARN("JVM cannot use large page memory because it does not have enough privilege to lock pages in memory.");
2871   }
2872 #undef WARN
2873 
2874   const size_t default_page_size = (size_t) vm_page_size();
2875   if (success && _large_page_size > default_page_size) {
2876     _page_sizes[0] = _large_page_size;
2877     _page_sizes[1] = default_page_size;
2878     _page_sizes[2] = 0;
2879   }
2880 
2881   cleanup_after_large_page_init();
2882   UseLargePages = success;
2883 }
2884 
2885 int os::create_file_for_heap(const char* dir) {
2886 
2887   const char name_template[] = "/jvmheap.XXXXXX";
2888   char *fullname = (char*)os::malloc((strlen(dir) + strlen(name_template) + 1), mtInternal);
2889   if (fullname == NULL) {
2890     vm_exit_during_initialization(err_msg("Malloc failed during creation of backing file for heap (%s)", os::strerror(errno)));
2891     return -1;
2892   }
2893 
2894   (void)strncpy(fullname, dir, strlen(dir)+1);
2895   (void)strncat(fullname, name_template, strlen(name_template));
2896 
2897   os::native_path(fullname);
2898 
2899   char *path = _mktemp(fullname);
2900   if (path == NULL) {
2901     warning("_mktemp could not create file name from template %s (%s)", fullname, os::strerror(errno));
2902     os::free(fullname);
2903     return -1;
2904   }
2905 
2906   int fd = _open(path, O_RDWR | O_CREAT | O_TEMPORARY | O_EXCL, S_IWRITE | S_IREAD);
2907 
2908   os::free(fullname);
2909   if (fd < 0) {
2910     warning("Problem opening file for heap (%s)", os::strerror(errno));
2911     return -1;
2912   }
2913   return fd;
2914 }
2915 
2916 // If 'base' is not NULL, function will return NULL if it cannot get 'base'
2917 char* os::map_memory_to_file(char* base, size_t size, int fd) {
2918   assert(fd != -1, "File descriptor is not valid");
2919 
2920   HANDLE fh = (HANDLE)_get_osfhandle(fd);
2921   HANDLE fileMapping = CreateFileMapping(fh, NULL, PAGE_READWRITE,
2922     (DWORD)(size >> 32), (DWORD)(size & 0xFFFFFFFF), NULL);
2923   if (fileMapping == NULL) {
2924     if (GetLastError() == ERROR_DISK_FULL) {
2925       vm_exit_during_initialization(err_msg("Could not allocate sufficient disk space for Java heap"));
2926     }
2927     else {
2928       vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));
2929     }
2930 
2931     return NULL;
2932   }
2933 
2934   LPVOID addr = MapViewOfFileEx(fileMapping, FILE_MAP_WRITE, 0, 0, size, base);
2935 
2936   CloseHandle(fileMapping);
2937 
2938   return (char*)addr;
2939 }
2940 
2941 char* os::replace_existing_mapping_with_file_mapping(char* base, size_t size, int fd) {
2942   assert(fd != -1, "File descriptor is not valid");
2943   assert(base != NULL, "Base address cannot be NULL");
2944 
2945   release_memory(base, size);
2946   return map_memory_to_file(base, size, fd);
2947 }
2948 
2949 // On win32, one cannot release just a part of reserved memory, it's an
2950 // all or nothing deal.  When we split a reservation, we must break the
2951 // reservation into two reservations.
2952 void os::pd_split_reserved_memory(char *base, size_t size, size_t split,
2953                                   bool realloc) {
2954   if (size > 0) {
2955     release_memory(base, size);
2956     if (realloc) {
2957       reserve_memory(split, base);
2958     }
2959     if (size != split) {
2960       reserve_memory(size - split, base + split);
2961     }
2962   }
2963 }
2964 
2965 // Multiple threads can race in this code but it's not possible to unmap small sections of
2966 // virtual space to get requested alignment, like posix-like os's.
2967 // Windows prevents multiple thread from remapping over each other so this loop is thread-safe.
2968 char* os::reserve_memory_aligned(size_t size, size_t alignment, int file_desc) {
2969   assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
2970          "Alignment must be a multiple of allocation granularity (page size)");
2971   assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");
2972 
2973   size_t extra_size = size + alignment;
2974   assert(extra_size >= size, "overflow, size is too large to allow alignment");
2975 
2976   char* aligned_base = NULL;
2977 
2978   do {
2979     char* extra_base = os::reserve_memory(extra_size, NULL, alignment, file_desc);
2980     if (extra_base == NULL) {
2981       return NULL;
2982     }
2983     // Do manual alignment
2984     aligned_base = align_up(extra_base, alignment);
2985 
2986     if (file_desc != -1) {
2987       os::unmap_memory(extra_base, extra_size);
2988     } else {
2989       os::release_memory(extra_base, extra_size);
2990     }
2991 
2992     aligned_base = os::reserve_memory(size, aligned_base, 0, file_desc);
2993 
2994   } while (aligned_base == NULL);
2995 
2996   return aligned_base;
2997 }
2998 
2999 char* os::pd_reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
3000   assert((size_t)addr % os::vm_allocation_granularity() == 0,
3001          "reserve alignment");
3002   assert(bytes % os::vm_page_size() == 0, "reserve page size");
3003   char* res;
3004   // note that if UseLargePages is on, all the areas that require interleaving
3005   // will go thru reserve_memory_special rather than thru here.
3006   bool use_individual = (UseNUMAInterleaving && !UseLargePages);
3007   if (!use_individual) {
3008     res = (char*)VirtualAlloc(addr, bytes, MEM_RESERVE, PAGE_READWRITE);
3009   } else {
3010     elapsedTimer reserveTimer;
3011     if (Verbose && PrintMiscellaneous) reserveTimer.start();
3012     // in numa interleaving, we have to allocate pages individually


3016       warning("NUMA page allocation failed");
3017     }
3018     if (Verbose && PrintMiscellaneous) {
3019       reserveTimer.stop();
3020       tty->print_cr("reserve_memory of %Ix bytes took " JLONG_FORMAT " ms (" JLONG_FORMAT " ticks)", bytes,
3021                     reserveTimer.milliseconds(), reserveTimer.ticks());
3022     }
3023   }
3024   assert(res == NULL || addr == NULL || addr == res,
3025          "Unexpected address from reserve.");
3026 
3027   return res;
3028 }
3029 
3030 // Reserve memory at an arbitrary address, only if that area is
3031 // available (and not reserved for something else).
3032 char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
3033   // Windows os::reserve_memory() fails of the requested address range is
3034   // not avilable.
3035   return reserve_memory(bytes, requested_addr);
3036 }
3037 
3038 char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr, int file_desc) {
3039   assert(file_desc >= 0, "file_desc is not valid");
3040   return map_memory_to_file(requested_addr, bytes, file_desc);
3041 }
3042 
3043 size_t os::large_page_size() {
3044   return _large_page_size;
3045 }
3046 
3047 bool os::can_commit_large_page_memory() {
3048   // Windows only uses large page memory when the entire region is reserved
3049   // and committed in a single VirtualAlloc() call. This may change in the
3050   // future, but with Windows 2003 it's not possible to commit on demand.
3051   return false;
3052 }
3053 
3054 bool os::can_execute_large_page_memory() {
3055   return true;
3056 }
3057 
3058 char* os::reserve_memory_special(size_t bytes, size_t alignment, char* addr,
3059                                  bool exec) {
3060   assert(UseLargePages, "only for large pages");


< prev index next >