2893 reserve_memory(size - split, base + split); |
2893 reserve_memory(size - split, base + split); |
2894 } |
2894 } |
2895 } |
2895 } |
2896 } |
2896 } |
2897 |
2897 |
|
2898 // Multiple threads can race in this code but it's not possible to unmap small sections of |
|
2899 // virtual space to get requested alignment, like posix-like os's. |
|
2900 // Windows prevents multiple thread from remapping over each other so this loop is thread-safe. |
|
2901 char* os::reserve_memory_aligned(size_t size, size_t alignment) { |
|
2902 assert((alignment & (os::vm_allocation_granularity() - 1)) == 0, |
|
2903 "Alignment must be a multiple of allocation granularity (page size)"); |
|
2904 assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned"); |
|
2905 |
|
2906 size_t extra_size = size + alignment; |
|
2907 assert(extra_size >= size, "overflow, size is too large to allow alignment"); |
|
2908 |
|
2909 char* aligned_base = NULL; |
|
2910 |
|
2911 do { |
|
2912 char* extra_base = os::reserve_memory(extra_size, NULL, alignment); |
|
2913 if (extra_base == NULL) { |
|
2914 return NULL; |
|
2915 } |
|
2916 // Do manual alignment |
|
2917 aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment); |
|
2918 |
|
2919 os::release_memory(extra_base, extra_size); |
|
2920 |
|
2921 aligned_base = os::reserve_memory(size, aligned_base); |
|
2922 |
|
2923 } while (aligned_base == NULL); |
|
2924 |
|
2925 return aligned_base; |
|
2926 } |
|
2927 |
2898 char* os::pd_reserve_memory(size_t bytes, char* addr, size_t alignment_hint) { |
2928 char* os::pd_reserve_memory(size_t bytes, char* addr, size_t alignment_hint) { |
2899 assert((size_t)addr % os::vm_allocation_granularity() == 0, |
2929 assert((size_t)addr % os::vm_allocation_granularity() == 0, |
2900 "reserve alignment"); |
2930 "reserve alignment"); |
2901 assert(bytes % os::vm_allocation_granularity() == 0, "reserve block size"); |
2931 assert(bytes % os::vm_allocation_granularity() == 0, "reserve block size"); |
2902 char* res; |
2932 char* res; |