Mercurial > hg > openjdk > jdk7u > hotspot
changeset 4393:0e8e9d990d91 jdk7u21-b05
Merge
author | asaha |
---|---|
date | Mon, 04 Mar 2013 12:34:25 -0800 |
parents | ee98e8e35da2 (current diff) bc3dc90c4e9e (diff) |
children | ae7be9b23555 |
files | |
diffstat | 5 files changed, 75 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/make/hotspot_version Mon Mar 04 11:40:45 2013 -0800 +++ b/make/hotspot_version Mon Mar 04 12:34:25 2013 -0800 @@ -34,7 +34,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013 HS_MAJOR_VER=23 -HS_MINOR_VER=7 +HS_MINOR_VER=21 HS_BUILD_NUMBER=01 JDK_MAJOR_VER=1
--- a/src/os/posix/vm/os_posix.cpp Mon Mar 04 11:40:45 2013 -0800 +++ b/src/os/posix/vm/os_posix.cpp Mon Mar 04 12:34:25 2013 -0800 @@ -75,6 +75,47 @@ return; } +// Multiple threads can race in this code, and can remap over each other with MAP_FIXED, +// so on posix, unmap the section at the start and at the end of the chunk that we mapped +// rather than unmapping and remapping the whole chunk to get requested alignment. +char* os::reserve_memory_aligned(size_t size, size_t alignment) { + assert((alignment & (os::vm_allocation_granularity() - 1)) == 0, + "Alignment must be a multiple of allocation granularity (page size)"); + assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned"); + + size_t extra_size = size + alignment; + assert(extra_size >= size, "overflow, size is too large to allow alignment"); + + char* extra_base = os::reserve_memory(extra_size, NULL, alignment); + + if (extra_base == NULL) { + return NULL; + } + + // Do manual alignment + char* aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment); + + // [ | | ] + // ^ extra_base + // ^ extra_base + begin_offset == aligned_base + // extra_base + begin_offset + size ^ + // extra_base + extra_size ^ + // |<>| == begin_offset + // end_offset == |<>| + size_t begin_offset = aligned_base - extra_base; + size_t end_offset = (extra_base + extra_size) - (aligned_base + size); + + if (begin_offset > 0) { + os::release_memory(extra_base, begin_offset); + } + + if (end_offset > 0) { + os::release_memory(extra_base + begin_offset + size, end_offset); + } + + return aligned_base; +} + void os::Posix::print_load_average(outputStream* st) { st->print("load average:"); double loadavg[3];
--- a/src/os/windows/vm/os_windows.cpp Mon Mar 04 11:40:45 2013 -0800 +++ b/src/os/windows/vm/os_windows.cpp Mon Mar 04 12:34:25 2013 -0800 @@ -2941,6 +2941,36 @@ } } +// Multiple threads can race in this code but it's not possible to unmap small sections of +// virtual space to get requested alignment, like posix-like os's. +// Windows prevents multiple thread from remapping over each other so this loop is thread-safe. +char* os::reserve_memory_aligned(size_t size, size_t alignment) { + assert((alignment & (os::vm_allocation_granularity() - 1)) == 0, + "Alignment must be a multiple of allocation granularity (page size)"); + assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned"); + + size_t extra_size = size + alignment; + assert(extra_size >= size, "overflow, size is too large to allow alignment"); + + char* aligned_base = NULL; + + do { + char* extra_base = os::reserve_memory(extra_size, NULL, alignment); + if (extra_base == NULL) { + return NULL; + } + // Do manual alignment + aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment); + + os::release_memory(extra_base, extra_size); + + aligned_base = os::reserve_memory(size, aligned_base); + + } while (aligned_base == NULL); + + return aligned_base; +} + char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) { assert((size_t)addr % os::vm_allocation_granularity() == 0, "reserve alignment");
--- a/src/share/vm/runtime/os.hpp Mon Mar 04 11:40:45 2013 -0800 +++ b/src/share/vm/runtime/os.hpp Mon Mar 04 12:34:25 2013 -0800 @@ -233,6 +233,7 @@ static int vm_allocation_granularity(); static char* reserve_memory(size_t bytes, char* addr = 0, size_t alignment_hint = 0); + static char* reserve_memory_aligned(size_t size, size_t alignment); static char* attempt_reserve_memory_at(size_t bytes, char* addr); static void split_reserved_memory(char *base, size_t size, size_t split, bool realloc);
--- a/src/share/vm/runtime/virtualspace.cpp Mon Mar 04 11:40:45 2013 -0800 +++ b/src/share/vm/runtime/virtualspace.cpp Mon Mar 04 12:34:25 2013 -0800 @@ -340,20 +340,9 @@ if ((((size_t)base + noaccess_prefix) & (alignment - 1)) != 0) { // Base not aligned, retry if (!os::release_memory(base, size)) fatal("os::release_memory failed"); - // Reserve size large enough to do manual alignment and - // increase size to a multiple of the desired alignment + // Make sure that size is aligned size = align_size_up(size, alignment); - size_t extra_size = size + alignment; - do { - char* extra_base = os::reserve_memory(extra_size, NULL, alignment); - if (extra_base == NULL) return; - // Do manual alignement - base = (char*) align_size_up((uintptr_t) extra_base, alignment); - assert(base >= extra_base, "just checking"); - // Re-reserve the region at the aligned base address. - os::release_memory(extra_base, extra_size); - base = os::reserve_memory(size, base); - } while (base == NULL); + base = os::reserve_memory_aligned(size, alignment); if (requested_address != 0 && failed_to_reserve_as_requested(base, requested_address, size, false)) {