hotspot/src/os/windows/vm/os_windows.cpp
changeset 10494 3f347ed8bd3c
parent 10247 d875b714a43a
child 10527 fedb7f148e85
equal deleted inserted replaced
10284:17533dd1b807 10494:3f347ed8bd3c
  2612 #endif
  2612 #endif
  2613 
  2613 
  2614 static HANDLE    _hProcess;
  2614 static HANDLE    _hProcess;
  2615 static HANDLE    _hToken;
  2615 static HANDLE    _hToken;
  2616 
  2616 
       
  2617 // Container for NUMA node list info
       
  2618 class NUMANodeListHolder {
       
  2619 private:
       
  2620   int *_numa_used_node_list;  // allocated below
       
  2621   int _numa_used_node_count;
       
  2622 
       
  2623   void free_node_list() {
       
  2624     if (_numa_used_node_list != NULL) {
       
  2625       FREE_C_HEAP_ARRAY(int, _numa_used_node_list);
       
  2626     }
       
  2627   }
       
  2628 
       
  2629 public:
       
  2630   NUMANodeListHolder() {
       
  2631     _numa_used_node_count = 0;
       
  2632     _numa_used_node_list = NULL;
       
  2633     // do rest of initialization in build routine (after function pointers are set up)
       
  2634   }
       
  2635 
       
  2636   ~NUMANodeListHolder() {
       
  2637     free_node_list();
       
  2638   }
       
  2639 
       
  2640   bool build() {
       
  2641     DWORD_PTR proc_aff_mask;
       
  2642     DWORD_PTR sys_aff_mask;
       
  2643     if (!GetProcessAffinityMask(GetCurrentProcess(), &proc_aff_mask, &sys_aff_mask)) return false;
       
  2644     ULONG highest_node_number;
       
  2645     if (!os::Kernel32Dll::GetNumaHighestNodeNumber(&highest_node_number)) return false;
       
  2646     free_node_list();
       
  2647     _numa_used_node_list = NEW_C_HEAP_ARRAY(int, highest_node_number);
       
  2648     for (unsigned int i = 0; i <= highest_node_number; i++) {
       
  2649       ULONGLONG proc_mask_numa_node;
       
  2650       if (!os::Kernel32Dll::GetNumaNodeProcessorMask(i, &proc_mask_numa_node)) return false;
       
  2651       if ((proc_aff_mask & proc_mask_numa_node)!=0) {
       
  2652         _numa_used_node_list[_numa_used_node_count++] = i;
       
  2653       }
       
  2654     }
       
  2655     return (_numa_used_node_count > 1);
       
  2656   }
       
  2657 
       
  2658   int get_count() {return _numa_used_node_count;}
       
  2659   int get_node_list_entry(int n) {
       
  2660     // for indexes out of range, returns -1
       
  2661     return (n < _numa_used_node_count ? _numa_used_node_list[n] : -1);
       
  2662   }
       
  2663 
       
  2664 } numa_node_list_holder;
       
  2665 
       
  2666 
       
  2667 
  2617 static size_t _large_page_size = 0;
  2668 static size_t _large_page_size = 0;
  2618 
  2669 
  2619 static bool resolve_functions_for_large_page_init() {
  2670 static bool resolve_functions_for_large_page_init() {
  2620   return os::Kernel32Dll::GetLargePageMinimumAvailable() &&
  2671   return os::Kernel32Dll::GetLargePageMinimumAvailable() &&
  2621     os::Advapi32Dll::AdvapiAvailable();
  2672     os::Advapi32Dll::AdvapiAvailable();
  2650   if (_hProcess) CloseHandle(_hProcess);
  2701   if (_hProcess) CloseHandle(_hProcess);
  2651   _hProcess = NULL;
  2702   _hProcess = NULL;
  2652   if (_hToken) CloseHandle(_hToken);
  2703   if (_hToken) CloseHandle(_hToken);
  2653   _hToken = NULL;
  2704   _hToken = NULL;
  2654 }
  2705 }
       
  2706 
       
  2707 static bool numa_interleaving_init() {
       
  2708   bool success = false;
       
  2709   bool use_numa_specified = !FLAG_IS_DEFAULT(UseNUMA);
       
  2710   bool use_numa_interleaving_specified = !FLAG_IS_DEFAULT(UseNUMAInterleaving);
       
  2711 
       
  2712   // print a warning if UseNUMA or UseNUMAInterleaving flag is specified on command line
       
  2713   bool warn_on_failure =  use_numa_specified || use_numa_interleaving_specified;
       
  2714 # define WARN(msg) if (warn_on_failure) { warning(msg); }
       
  2715 
       
  2716   // NUMAInterleaveGranularity cannot be less than vm_allocation_granularity (or _large_page_size if using large pages)
       
  2717   size_t min_interleave_granularity = UseLargePages ? _large_page_size : os::vm_allocation_granularity();
       
  2718   NUMAInterleaveGranularity = align_size_up(NUMAInterleaveGranularity, min_interleave_granularity);
       
  2719 
       
  2720   if (os::Kernel32Dll::NumaCallsAvailable()) {
       
  2721     if (numa_node_list_holder.build()) {
       
  2722       if (PrintMiscellaneous && Verbose) {
       
  2723         tty->print("NUMA UsedNodeCount=%d, namely ", os::numa_get_groups_num());
       
  2724         for (int i = 0; i < numa_node_list_holder.get_count(); i++) {
       
  2725           tty->print("%d ", numa_node_list_holder.get_node_list_entry(i));
       
  2726         }
       
  2727         tty->print("\n");
       
  2728       }
       
  2729       success = true;
       
  2730     } else {
       
  2731       WARN("Process does not cover multiple NUMA nodes.");
       
  2732     }
       
  2733   } else {
       
  2734     WARN("NUMA Interleaving is not supported by the operating system.");
       
  2735   }
       
  2736   if (!success) {
       
  2737     if (use_numa_specified) WARN("...Ignoring UseNUMA flag.");
       
  2738     if (use_numa_interleaving_specified) WARN("...Ignoring UseNUMAInterleaving flag.");
       
  2739   }
       
  2740   return success;
       
  2741 #undef WARN
       
  2742 }
       
  2743 
       
  2744 // this routine is used whenever we need to reserve a contiguous VA range
       
  2745 // but we need to make separate VirtualAlloc calls for each piece of the range
       
  2746 // Reasons for doing this:
       
  2747 //  * UseLargePagesIndividualAllocation was set (normally only needed on WS2003 but possible to be set otherwise)
       
  2748 //  * UseNUMAInterleaving requires a separate node for each piece
       
  2749 static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags, DWORD prot,
       
  2750                                          bool should_inject_error=false) {
       
  2751   char * p_buf;
       
  2752   // note: at setup time we guaranteed that NUMAInterleaveGranularity was aligned up to a page size
       
  2753   size_t page_size = UseLargePages ? _large_page_size : os::vm_allocation_granularity();
       
  2754   size_t chunk_size = UseNUMAInterleaving ? NUMAInterleaveGranularity : page_size;
       
  2755 
       
  2756   // first reserve enough address space in advance since we want to be
       
  2757   // able to break a single contiguous virtual address range into multiple
       
  2758   // large page commits but WS2003 does not allow reserving large page space
       
  2759   // so we just use 4K pages for reserve, this gives us a legal contiguous
       
  2760   // address space. then we will deallocate that reservation, and re alloc
       
  2761   // using large pages
       
  2762   const size_t size_of_reserve = bytes + chunk_size;
       
  2763   if (bytes > size_of_reserve) {
       
  2764     // Overflowed.
       
  2765     return NULL;
       
  2766   }
       
  2767   p_buf = (char *) VirtualAlloc(addr,
       
  2768                                 size_of_reserve,  // size of Reserve
       
  2769                                 MEM_RESERVE,
       
  2770                                 PAGE_READWRITE);
       
  2771   // If reservation failed, return NULL
       
  2772   if (p_buf == NULL) return NULL;
       
  2773 
       
  2774   os::release_memory(p_buf, bytes + chunk_size);
       
  2775 
       
  2776   // we still need to round up to a page boundary (in case we are using large pages)
       
  2777   // but not to a chunk boundary (in case InterleavingGranularity doesn't align with page size)
       
  2778   // instead we handle this in the bytes_to_rq computation below
       
  2779   p_buf = (char *) align_size_up((size_t)p_buf, page_size);
       
  2780 
       
  2781   // now go through and allocate one chunk at a time until all bytes are
       
  2782   // allocated
       
  2783   size_t  bytes_remaining = bytes;
       
  2784   // An overflow of align_size_up() would have been caught above
       
  2785   // in the calculation of size_of_reserve.
       
  2786   char * next_alloc_addr = p_buf;
       
  2787   HANDLE hProc = GetCurrentProcess();
       
  2788 
       
  2789 #ifdef ASSERT
       
  2790   // Variable for the failure injection
       
  2791   long ran_num = os::random();
       
  2792   size_t fail_after = ran_num % bytes;
       
  2793 #endif
       
  2794 
       
  2795   int count=0;
       
  2796   while (bytes_remaining) {
       
  2797     // select bytes_to_rq to get to the next chunk_size boundary
       
  2798 
       
  2799     size_t bytes_to_rq = MIN2(bytes_remaining, chunk_size - ((size_t)next_alloc_addr % chunk_size));
       
  2800     // Note allocate and commit
       
  2801     char * p_new;
       
  2802 
       
  2803 #ifdef ASSERT
       
  2804     bool inject_error_now = should_inject_error && (bytes_remaining <= fail_after);
       
  2805 #else
       
  2806     const bool inject_error_now = false;
       
  2807 #endif
       
  2808 
       
  2809     if (inject_error_now) {
       
  2810       p_new = NULL;
       
  2811     } else {
       
  2812       if (!UseNUMAInterleaving) {
       
  2813         p_new = (char *) VirtualAlloc(next_alloc_addr,
       
  2814                                       bytes_to_rq,
       
  2815                                       flags,
       
  2816                                       prot);
       
  2817       } else {
       
  2818         // get the next node to use from the used_node_list
       
  2819         DWORD node = numa_node_list_holder.get_node_list_entry(count % os::numa_get_groups_num());
       
  2820         p_new = (char *)os::Kernel32Dll::VirtualAllocExNuma(hProc,
       
  2821                                                             next_alloc_addr,
       
  2822                                                             bytes_to_rq,
       
  2823                                                             flags,
       
  2824                                                             prot,
       
  2825                                                             node);
       
  2826       }
       
  2827     }
       
  2828 
       
  2829     if (p_new == NULL) {
       
  2830       // Free any allocated pages
       
  2831       if (next_alloc_addr > p_buf) {
       
  2832         // Some memory was committed so release it.
       
  2833         size_t bytes_to_release = bytes - bytes_remaining;
       
  2834         os::release_memory(p_buf, bytes_to_release);
       
  2835       }
       
  2836 #ifdef ASSERT
       
  2837       if (should_inject_error) {
       
  2838         if (TracePageSizes && Verbose) {
       
  2839           tty->print_cr("Reserving pages individually failed.");
       
  2840         }
       
  2841       }
       
  2842 #endif
       
  2843       return NULL;
       
  2844     }
       
  2845     bytes_remaining -= bytes_to_rq;
       
  2846     next_alloc_addr += bytes_to_rq;
       
  2847     count++;
       
  2848   }
       
  2849   // made it this far, success
       
  2850   return p_buf;
       
  2851 }
       
  2852 
       
  2853 
  2655 
  2854 
  2656 void os::large_page_init() {
  2855 void os::large_page_init() {
  2657   if (!UseLargePages) return;
  2856   if (!UseLargePages) return;
  2658 
  2857 
  2659   // print a warning if any large page related flag is specified on command line
  2858   // print a warning if any large page related flag is specified on command line
  2720 
  2919 
  2721 char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
  2920 char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
  2722   assert((size_t)addr % os::vm_allocation_granularity() == 0,
  2921   assert((size_t)addr % os::vm_allocation_granularity() == 0,
  2723          "reserve alignment");
  2922          "reserve alignment");
  2724   assert(bytes % os::vm_allocation_granularity() == 0, "reserve block size");
  2923   assert(bytes % os::vm_allocation_granularity() == 0, "reserve block size");
  2725   char* res = (char*)VirtualAlloc(addr, bytes, MEM_RESERVE, PAGE_READWRITE);
  2924   char* res;
       
  2925   // note that if UseLargePages is on, all the areas that require interleaving
       
  2926   // will go thru reserve_memory_special rather than thru here.
       
  2927   bool use_individual = (UseNUMAInterleaving && !UseLargePages);
       
  2928   if (!use_individual) {
       
  2929     res = (char*)VirtualAlloc(addr, bytes, MEM_RESERVE, PAGE_READWRITE);
       
  2930   } else {
       
  2931     elapsedTimer reserveTimer;
       
  2932     if( Verbose && PrintMiscellaneous ) reserveTimer.start();
       
  2933     // in numa interleaving, we have to allocate pages individually
       
  2934     // (well really chunks of NUMAInterleaveGranularity size)
       
  2935     res = allocate_pages_individually(bytes, addr, MEM_RESERVE, PAGE_READWRITE);
       
  2936     if (res == NULL) {
       
  2937       warning("NUMA page allocation failed");
       
  2938     }
       
  2939     if( Verbose && PrintMiscellaneous ) {
       
  2940       reserveTimer.stop();
       
  2941       tty->print_cr("reserve_memory of %Ix bytes took %ld ms (%ld ticks)", bytes,
       
  2942                     reserveTimer.milliseconds(), reserveTimer.ticks());
       
  2943     }
       
  2944   }
  2726   assert(res == NULL || addr == NULL || addr == res,
  2945   assert(res == NULL || addr == NULL || addr == res,
  2727          "Unexpected address from reserve.");
  2946          "Unexpected address from reserve.");
       
  2947 
  2728   return res;
  2948   return res;
  2729 }
  2949 }
  2730 
  2950 
  2731 // Reserve memory at an arbitrary address, only if that area is
  2951 // Reserve memory at an arbitrary address, only if that area is
  2732 // available (and not reserved for something else).
  2952 // available (and not reserved for something else).
  2752 }
  2972 }
  2753 
  2973 
  2754 char* os::reserve_memory_special(size_t bytes, char* addr, bool exec) {
  2974 char* os::reserve_memory_special(size_t bytes, char* addr, bool exec) {
  2755 
  2975 
  2756   const DWORD prot = exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
  2976   const DWORD prot = exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
  2757 
  2977   const DWORD flags = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
  2758   if (UseLargePagesIndividualAllocation) {
  2978 
       
  2979   // with large pages, there are two cases where we need to use Individual Allocation
       
  2980   // 1) the UseLargePagesIndividualAllocation flag is set (set by default on WS2003)
       
  2981   // 2) NUMA Interleaving is enabled, in which case we use a different node for each page
       
  2982   if (UseLargePagesIndividualAllocation || UseNUMAInterleaving) {
  2759     if (TracePageSizes && Verbose) {
  2983     if (TracePageSizes && Verbose) {
  2760        tty->print_cr("Reserving large pages individually.");
  2984        tty->print_cr("Reserving large pages individually.");
  2761     }
  2985     }
  2762     char * p_buf;
  2986     char * p_buf = allocate_pages_individually(bytes, addr, flags, prot, LargePagesIndividualAllocationInjectError);
  2763     // first reserve enough address space in advance since we want to be
  2987     if (p_buf == NULL) {
  2764     // able to break a single contiguous virtual address range into multiple
  2988       // give an appropriate warning message
  2765     // large page commits but WS2003 does not allow reserving large page space
  2989       if (UseNUMAInterleaving) {
  2766     // so we just use 4K pages for reserve, this gives us a legal contiguous
  2990         warning("NUMA large page allocation failed, UseLargePages flag ignored");
  2767     // address space. then we will deallocate that reservation, and re alloc
  2991       }
  2768     // using large pages
  2992       if (UseLargePagesIndividualAllocation) {
  2769     const size_t size_of_reserve = bytes + _large_page_size;
  2993         warning("Individually allocated large pages failed, "
  2770     if (bytes > size_of_reserve) {
  2994                 "use -XX:-UseLargePagesIndividualAllocation to turn off");
  2771       // Overflowed.
  2995       }
  2772       warning("Individually allocated large pages failed, "
       
  2773         "use -XX:-UseLargePagesIndividualAllocation to turn off");
       
  2774       return NULL;
  2996       return NULL;
  2775     }
       
  2776     p_buf = (char *) VirtualAlloc(addr,
       
  2777                                  size_of_reserve,  // size of Reserve
       
  2778                                  MEM_RESERVE,
       
  2779                                  PAGE_READWRITE);
       
  2780     // If reservation failed, return NULL
       
  2781     if (p_buf == NULL) return NULL;
       
  2782 
       
  2783     release_memory(p_buf, bytes + _large_page_size);
       
  2784     // round up to page boundary.  If the size_of_reserve did not
       
  2785     // overflow and the reservation did not fail, this align up
       
  2786     // should not overflow.
       
  2787     p_buf = (char *) align_size_up((size_t)p_buf, _large_page_size);
       
  2788 
       
  2789     // now go through and allocate one page at a time until all bytes are
       
  2790     // allocated
       
  2791     size_t  bytes_remaining = align_size_up(bytes, _large_page_size);
       
  2792     // An overflow of align_size_up() would have been caught above
       
  2793     // in the calculation of size_of_reserve.
       
  2794     char * next_alloc_addr = p_buf;
       
  2795 
       
  2796 #ifdef ASSERT
       
  2797     // Variable for the failure injection
       
  2798     long ran_num = os::random();
       
  2799     size_t fail_after = ran_num % bytes;
       
  2800 #endif
       
  2801 
       
  2802     while (bytes_remaining) {
       
  2803       size_t bytes_to_rq = MIN2(bytes_remaining, _large_page_size);
       
  2804       // Note allocate and commit
       
  2805       char * p_new;
       
  2806 
       
  2807 #ifdef ASSERT
       
  2808       bool inject_error = LargePagesIndividualAllocationInjectError &&
       
  2809           (bytes_remaining <= fail_after);
       
  2810 #else
       
  2811       const bool inject_error = false;
       
  2812 #endif
       
  2813 
       
  2814       if (inject_error) {
       
  2815         p_new = NULL;
       
  2816       } else {
       
  2817         p_new = (char *) VirtualAlloc(next_alloc_addr,
       
  2818                                     bytes_to_rq,
       
  2819                                     MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES,
       
  2820                                     prot);
       
  2821       }
       
  2822 
       
  2823       if (p_new == NULL) {
       
  2824         // Free any allocated pages
       
  2825         if (next_alloc_addr > p_buf) {
       
  2826           // Some memory was committed so release it.
       
  2827           size_t bytes_to_release = bytes - bytes_remaining;
       
  2828           release_memory(p_buf, bytes_to_release);
       
  2829         }
       
  2830 #ifdef ASSERT
       
  2831         if (UseLargePagesIndividualAllocation &&
       
  2832             LargePagesIndividualAllocationInjectError) {
       
  2833           if (TracePageSizes && Verbose) {
       
  2834              tty->print_cr("Reserving large pages individually failed.");
       
  2835           }
       
  2836         }
       
  2837 #endif
       
  2838         return NULL;
       
  2839       }
       
  2840       bytes_remaining -= bytes_to_rq;
       
  2841       next_alloc_addr += bytes_to_rq;
       
  2842     }
  2997     }
  2843 
  2998 
  2844     return p_buf;
  2999     return p_buf;
  2845 
  3000 
  2846   } else {
  3001   } else {
  2865   }
  3020   }
  2866   assert((size_t) addr % os::vm_page_size() == 0, "commit on page boundaries");
  3021   assert((size_t) addr % os::vm_page_size() == 0, "commit on page boundaries");
  2867   assert(bytes % os::vm_page_size() == 0, "commit in page-sized chunks");
  3022   assert(bytes % os::vm_page_size() == 0, "commit in page-sized chunks");
  2868   // Don't attempt to print anything if the OS call fails. We're
  3023   // Don't attempt to print anything if the OS call fails. We're
  2869   // probably low on resources, so the print itself may cause crashes.
  3024   // probably low on resources, so the print itself may cause crashes.
  2870   bool result = VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) != 0;
  3025 
  2871   if (result != NULL && exec) {
  3026   // unless we have NUMAInterleaving enabled, the range of a commit
  2872     DWORD oldprot;
  3027   // is always within a reserve covered by a single VirtualAlloc
  2873     // Windows doc says to use VirtualProtect to get execute permissions
  3028   // in that case we can just do a single commit for the requested size
  2874     return VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot) != 0;
  3029   if (!UseNUMAInterleaving) {
       
  3030     if (VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) == NULL) return false;
       
  3031     if (exec) {
       
  3032       DWORD oldprot;
       
  3033       // Windows doc says to use VirtualProtect to get execute permissions
       
  3034       if (!VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot)) return false;
       
  3035     }
       
  3036     return true;
  2875   } else {
  3037   } else {
  2876     return result;
  3038 
  2877   }
  3039     // when NUMAInterleaving is enabled, the commit might cover a range that
       
  3040     // came from multiple VirtualAlloc reserves (using allocate_pages_individually).
       
  3041     // VirtualQuery can help us determine that.  The RegionSize that VirtualQuery
       
  3042     // returns represents the number of bytes that can be committed in one step.
       
  3043     size_t bytes_remaining = bytes;
       
  3044     char * next_alloc_addr = addr;
       
  3045     while (bytes_remaining > 0) {
       
  3046       MEMORY_BASIC_INFORMATION alloc_info;
       
  3047       VirtualQuery(next_alloc_addr, &alloc_info, sizeof(alloc_info));
       
  3048       size_t bytes_to_rq = MIN2(bytes_remaining, (size_t)alloc_info.RegionSize);
       
  3049       if (VirtualAlloc(next_alloc_addr, bytes_to_rq, MEM_COMMIT, PAGE_READWRITE) == NULL)
       
  3050         return false;
       
  3051       if (exec) {
       
  3052         DWORD oldprot;
       
  3053         if (!VirtualProtect(next_alloc_addr, bytes_to_rq, PAGE_EXECUTE_READWRITE, &oldprot))
       
  3054           return false;
       
  3055       }
       
  3056       bytes_remaining -= bytes_to_rq;
       
  3057       next_alloc_addr += bytes_to_rq;
       
  3058     }
       
  3059   }
       
  3060   // if we made it this far, return true
       
  3061   return true;
  2878 }
  3062 }
  2879 
  3063 
  2880 bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
  3064 bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
  2881                        bool exec) {
  3065                        bool exec) {
  2882   return commit_memory(addr, size, exec);
  3066   return commit_memory(addr, size, exec);
  2946 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }
  3130 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }
  2947 void os::free_memory(char *addr, size_t bytes)         { }
  3131 void os::free_memory(char *addr, size_t bytes)         { }
  2948 void os::numa_make_global(char *addr, size_t bytes)    { }
  3132 void os::numa_make_global(char *addr, size_t bytes)    { }
  2949 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint)    { }
  3133 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint)    { }
  2950 bool os::numa_topology_changed()                       { return false; }
  3134 bool os::numa_topology_changed()                       { return false; }
  2951 size_t os::numa_get_groups_num()                       { return 1; }
  3135 size_t os::numa_get_groups_num()                       { return numa_node_list_holder.get_count(); }
  2952 int os::numa_get_group_id()                            { return 0; }
  3136 int os::numa_get_group_id()                            { return 0; }
  2953 size_t os::numa_get_leaf_groups(int *ids, size_t size) {
  3137 size_t os::numa_get_leaf_groups(int *ids, size_t size) {
  2954   if (size > 0) {
  3138   // check for size bigger than actual groups_num
  2955     ids[0] = 0;
  3139   size = MIN2(size, numa_get_groups_num());
  2956     return 1;
  3140   for (int i = 0; i < (int)size; i++) {
  2957   }
  3141     ids[i] = numa_node_list_holder.get_node_list_entry(i);
  2958   return 0;
  3142   }
       
  3143   return size;
  2959 }
  3144 }
  2960 
  3145 
  2961 bool os::get_page_info(char *start, page_info* info) {
  3146 bool os::get_page_info(char *start, page_info* info) {
  2962   return false;
  3147   return false;
  2963 }
  3148 }
  3478 
  3663 
  3479 #ifndef PRODUCT
  3664 #ifndef PRODUCT
  3480     if(Verbose && PrintMiscellaneous)
  3665     if(Verbose && PrintMiscellaneous)
  3481       tty->print("[Memory Serialize  Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
  3666       tty->print("[Memory Serialize  Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
  3482 #endif
  3667 #endif
  3483 }
  3668   }
  3484 
  3669 
  3485   os::large_page_init();
  3670   os::large_page_init();
  3486 
  3671 
  3487   // Setup Windows Exceptions
  3672   // Setup Windows Exceptions
  3488 
  3673 
  3581 #endif
  3766 #endif
  3582 
  3767 
  3583   // initialize thread priority policy
  3768   // initialize thread priority policy
  3584   prio_init();
  3769   prio_init();
  3585 
  3770 
  3586   if (UseNUMA && !ForceNUMA) {
  3771   if (UseNUMAInterleaving) {
  3587     UseNUMA = false; // Currently unsupported.
  3772     // first check whether this Windows OS supports VirtualAllocExNuma, if not ignore this flag
       
  3773     bool success = numa_interleaving_init();
       
  3774     if (!success) UseNUMAInterleaving = false;
  3588   }
  3775   }
  3589 
  3776 
  3590   return JNI_OK;
  3777   return JNI_OK;
  3591 }
  3778 }
  3592 
  3779 
  4756 }
  4943 }
  4757 
  4944 
  4758 
  4945 
  4759 // Kernel32 API
  4946 // Kernel32 API
  4760 typedef SIZE_T (WINAPI* GetLargePageMinimum_Fn)(void);
  4947 typedef SIZE_T (WINAPI* GetLargePageMinimum_Fn)(void);
       
  4948 typedef LPVOID (WINAPI *VirtualAllocExNuma_Fn) (HANDLE, LPVOID, SIZE_T, DWORD, DWORD, DWORD);
       
  4949 typedef BOOL (WINAPI *GetNumaHighestNodeNumber_Fn) (PULONG);
       
  4950 typedef BOOL (WINAPI *GetNumaNodeProcessorMask_Fn) (UCHAR, PULONGLONG);
       
  4951 
  4761 GetLargePageMinimum_Fn      os::Kernel32Dll::_GetLargePageMinimum = NULL;
  4952 GetLargePageMinimum_Fn      os::Kernel32Dll::_GetLargePageMinimum = NULL;
       
  4953 VirtualAllocExNuma_Fn       os::Kernel32Dll::_VirtualAllocExNuma = NULL;
       
  4954 GetNumaHighestNodeNumber_Fn os::Kernel32Dll::_GetNumaHighestNodeNumber = NULL;
       
  4955 GetNumaNodeProcessorMask_Fn os::Kernel32Dll::_GetNumaNodeProcessorMask = NULL;
  4762 BOOL                        os::Kernel32Dll::initialized = FALSE;
  4956 BOOL                        os::Kernel32Dll::initialized = FALSE;
  4763 SIZE_T os::Kernel32Dll::GetLargePageMinimum() {
  4957 SIZE_T os::Kernel32Dll::GetLargePageMinimum() {
  4764   assert(initialized && _GetLargePageMinimum != NULL,
  4958   assert(initialized && _GetLargePageMinimum != NULL,
  4765     "GetLargePageMinimumAvailable() not yet called");
  4959     "GetLargePageMinimumAvailable() not yet called");
  4766   return _GetLargePageMinimum();
  4960   return _GetLargePageMinimum();
  4771     initialize();
  4965     initialize();
  4772   }
  4966   }
  4773   return _GetLargePageMinimum != NULL;
  4967   return _GetLargePageMinimum != NULL;
  4774 }
  4968 }
  4775 
  4969 
  4776 
  4970 BOOL os::Kernel32Dll::NumaCallsAvailable() {
  4777 #ifndef JDK6_OR_EARLIER
  4971   if (!initialized) {
  4778 
  4972     initialize();
  4779 void os::Kernel32Dll::initialize() {
  4973   }
       
  4974   return _VirtualAllocExNuma != NULL;
       
  4975 }
       
  4976 
       
  4977 LPVOID os::Kernel32Dll::VirtualAllocExNuma(HANDLE hProc, LPVOID addr, SIZE_T bytes, DWORD flags, DWORD prot, DWORD node) {
       
  4978   assert(initialized && _VirtualAllocExNuma != NULL,
       
  4979     "NUMACallsAvailable() not yet called");
       
  4980 
       
  4981   return _VirtualAllocExNuma(hProc, addr, bytes, flags, prot, node);
       
  4982 }
       
  4983 
       
  4984 BOOL os::Kernel32Dll::GetNumaHighestNodeNumber(PULONG ptr_highest_node_number) {
       
  4985   assert(initialized && _GetNumaHighestNodeNumber != NULL,
       
  4986     "NUMACallsAvailable() not yet called");
       
  4987 
       
  4988   return _GetNumaHighestNodeNumber(ptr_highest_node_number);
       
  4989 }
       
  4990 
       
  4991 BOOL os::Kernel32Dll::GetNumaNodeProcessorMask(UCHAR node, PULONGLONG proc_mask) {
       
  4992   assert(initialized && _GetNumaNodeProcessorMask != NULL,
       
  4993     "NUMACallsAvailable() not yet called");
       
  4994 
       
  4995   return _GetNumaNodeProcessorMask(node, proc_mask);
       
  4996 }
       
  4997 
       
  4998 
       
  4999 void os::Kernel32Dll::initializeCommon() {
  4780   if (!initialized) {
  5000   if (!initialized) {
  4781     HMODULE handle = ::GetModuleHandle("Kernel32.dll");
  5001     HMODULE handle = ::GetModuleHandle("Kernel32.dll");
  4782     assert(handle != NULL, "Just check");
  5002     assert(handle != NULL, "Just check");
  4783     _GetLargePageMinimum = (GetLargePageMinimum_Fn)::GetProcAddress(handle, "GetLargePageMinimum");
  5003     _GetLargePageMinimum = (GetLargePageMinimum_Fn)::GetProcAddress(handle, "GetLargePageMinimum");
       
  5004     _VirtualAllocExNuma = (VirtualAllocExNuma_Fn)::GetProcAddress(handle, "VirtualAllocExNuma");
       
  5005     _GetNumaHighestNodeNumber = (GetNumaHighestNodeNumber_Fn)::GetProcAddress(handle, "GetNumaHighestNodeNumber");
       
  5006     _GetNumaNodeProcessorMask = (GetNumaNodeProcessorMask_Fn)::GetProcAddress(handle, "GetNumaNodeProcessorMask");
  4784     initialized = TRUE;
  5007     initialized = TRUE;
  4785   }
  5008   }
       
  5009 }
       
  5010 
       
  5011 
       
  5012 
       
  5013 #ifndef JDK6_OR_EARLIER
       
  5014 
       
  5015 void os::Kernel32Dll::initialize() {
       
  5016   initializeCommon();
  4786 }
  5017 }
  4787 
  5018 
  4788 
  5019 
  4789 // Kernel32 API
  5020 // Kernel32 API
  4790 inline BOOL os::Kernel32Dll::SwitchToThread() {
  5021 inline BOOL os::Kernel32Dll::SwitchToThread() {
  4885 CreateToolhelp32Snapshot_Fn os::Kernel32Dll::_CreateToolhelp32Snapshot = NULL;
  5116 CreateToolhelp32Snapshot_Fn os::Kernel32Dll::_CreateToolhelp32Snapshot = NULL;
  4886 Module32First_Fn            os::Kernel32Dll::_Module32First = NULL;
  5117 Module32First_Fn            os::Kernel32Dll::_Module32First = NULL;
  4887 Module32Next_Fn             os::Kernel32Dll::_Module32Next = NULL;
  5118 Module32Next_Fn             os::Kernel32Dll::_Module32Next = NULL;
  4888 GetNativeSystemInfo_Fn      os::Kernel32Dll::_GetNativeSystemInfo = NULL;
  5119 GetNativeSystemInfo_Fn      os::Kernel32Dll::_GetNativeSystemInfo = NULL;
  4889 
  5120 
       
  5121 
  4890 void os::Kernel32Dll::initialize() {
  5122 void os::Kernel32Dll::initialize() {
  4891   if (!initialized) {
  5123   if (!initialized) {
  4892     HMODULE handle = ::GetModuleHandle("Kernel32.dll");
  5124     HMODULE handle = ::GetModuleHandle("Kernel32.dll");
  4893     assert(handle != NULL, "Just check");
  5125     assert(handle != NULL, "Just check");
  4894 
  5126 
  4895     _SwitchToThread = (SwitchToThread_Fn)::GetProcAddress(handle, "SwitchToThread");
  5127     _SwitchToThread = (SwitchToThread_Fn)::GetProcAddress(handle, "SwitchToThread");
  4896     _GetLargePageMinimum = (GetLargePageMinimum_Fn)::GetProcAddress(handle, "GetLargePageMinimum");
       
  4897     _CreateToolhelp32Snapshot = (CreateToolhelp32Snapshot_Fn)
  5128     _CreateToolhelp32Snapshot = (CreateToolhelp32Snapshot_Fn)
  4898       ::GetProcAddress(handle, "CreateToolhelp32Snapshot");
  5129       ::GetProcAddress(handle, "CreateToolhelp32Snapshot");
  4899     _Module32First = (Module32First_Fn)::GetProcAddress(handle, "Module32First");
  5130     _Module32First = (Module32First_Fn)::GetProcAddress(handle, "Module32First");
  4900     _Module32Next = (Module32Next_Fn)::GetProcAddress(handle, "Module32Next");
  5131     _Module32Next = (Module32Next_Fn)::GetProcAddress(handle, "Module32Next");
  4901     _GetNativeSystemInfo = (GetNativeSystemInfo_Fn)::GetProcAddress(handle, "GetNativeSystemInfo");
  5132     _GetNativeSystemInfo = (GetNativeSystemInfo_Fn)::GetProcAddress(handle, "GetNativeSystemInfo");
       
  5133     initializeCommon();  // resolve the functions that always need resolving
  4902 
  5134 
  4903     initialized = TRUE;
  5135     initialized = TRUE;
  4904   }
  5136   }
  4905 }
  5137 }
  4906 
  5138 
  4961   assert(initialized && _GetNativeSystemInfo != NULL,
  5193   assert(initialized && _GetNativeSystemInfo != NULL,
  4962     "GetNativeSystemInfoAvailable() not yet called");
  5194     "GetNativeSystemInfoAvailable() not yet called");
  4963 
  5195 
  4964   _GetNativeSystemInfo(lpSystemInfo);
  5196   _GetNativeSystemInfo(lpSystemInfo);
  4965 }
  5197 }
       
  5198 
       
  5199 
  4966 
  5200 
  4967 // PSAPI API
  5201 // PSAPI API
  4968 
  5202 
  4969 
  5203 
  4970 typedef BOOL (WINAPI *EnumProcessModules_Fn)(HANDLE, HMODULE *, DWORD, LPDWORD);
  5204 typedef BOOL (WINAPI *EnumProcessModules_Fn)(HANDLE, HMODULE *, DWORD, LPDWORD);