hotspot/src/os/linux/vm/os_linux.cpp
changeset 5085 4f0c435f8c3c
parent 4493 9204129f065e
child 5090 fd9498f26582
equal deleted inserted replaced
5043:df4fadccc378 5085:4f0c435f8c3c
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    21  * have any questions.
    22  *
    22  *
    23  */
    23  */
       
    24 
       
    25 # define __STDC_FORMAT_MACROS
    24 
    26 
    25 // do not include  precompiled  header file
    27 // do not include  precompiled  header file
    26 # include "incls/_os_linux.cpp.incl"
    28 # include "incls/_os_linux.cpp.incl"
    27 
    29 
    28 // put OS-includes here
    30 // put OS-includes here
    51 # include <sys/sysinfo.h>
    53 # include <sys/sysinfo.h>
    52 # include <gnu/libc-version.h>
    54 # include <gnu/libc-version.h>
    53 # include <sys/ipc.h>
    55 # include <sys/ipc.h>
    54 # include <sys/shm.h>
    56 # include <sys/shm.h>
    55 # include <link.h>
    57 # include <link.h>
       
    58 # include <stdint.h>
       
    59 # include <inttypes.h>
    56 
    60 
    57 #define MAX_PATH    (2 * K)
    61 #define MAX_PATH    (2 * K)
    58 
    62 
    59 // for timer info max values which include all bits
    63 // for timer info max values which include all bits
    60 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
    64 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
  2488 
  2492 
  2489 bool os::uncommit_memory(char* addr, size_t size) {
  2493 bool os::uncommit_memory(char* addr, size_t size) {
  2490   return ::mmap(addr, size, PROT_NONE,
  2494   return ::mmap(addr, size, PROT_NONE,
  2491                 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0)
  2495                 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0)
  2492     != MAP_FAILED;
  2496     != MAP_FAILED;
       
  2497 }
       
  2498 
       
  2499 // Linux uses a growable mapping for the stack, and if the mapping for
       
  2500 // the stack guard pages is not removed when we detach a thread the
       
  2501 // stack cannot grow beyond the pages where the stack guard was
       
  2502 // mapped.  If at some point later in the process the stack expands to
       
  2503 // that point, the Linux kernel cannot expand the stack any further
       
  2504 // because the guard pages are in the way, and a segfault occurs.
       
  2505 //
       
  2506 // However, it's essential not to split the stack region by unmapping
       
  2507 // a region (leaving a hole) that's already part of the stack mapping,
       
  2508 // so if the stack mapping has already grown beyond the guard pages at
       
  2509 // the time we create them, we have to truncate the stack mapping.
       
  2510 // So, we need to know the extent of the stack mapping when
       
  2511 // create_stack_guard_pages() is called.
       
  2512 
       
  2513 // Find the bounds of the stack mapping.  Return true for success.
       
  2514 //
       
  2515 // We only need this for stacks that are growable: at the time of
       
  2516 // writing thread stacks don't use growable mappings (i.e. those
       
  2517 // creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this
       
  2518 // only applies to the main thread.
       
  2519 static bool
       
  2520 get_stack_bounds(uintptr_t *bottom, uintptr_t *top)
       
  2521 {
       
  2522   FILE *f = fopen("/proc/self/maps", "r");
       
  2523   if (f == NULL)
       
  2524     return false;
       
  2525 
       
  2526   while (!feof(f)) {
       
  2527     size_t dummy;
       
  2528     char *str = NULL;
       
  2529     ssize_t len = getline(&str, &dummy, f);
       
  2530     if (len == -1) {
       
  2531       return false;
       
  2532     }
       
  2533 
       
  2534     if (len > 0 && str[len-1] == '\n') {
       
  2535       str[len-1] = 0;
       
  2536       len--;
       
  2537     }
       
  2538 
       
  2539     static const char *stack_str = "[stack]";
       
  2540     if (len > (ssize_t)strlen(stack_str)
       
  2541        && (strcmp(str + len - strlen(stack_str), stack_str) == 0)) {
       
  2542       if (sscanf(str, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) {
       
  2543         uintptr_t sp = (uintptr_t)__builtin_frame_address(0);
       
  2544         if (sp >= *bottom && sp <= *top) {
       
  2545           free(str);
       
  2546           return true;
       
  2547         }
       
  2548       }
       
  2549     }
       
  2550 
       
  2551     free(str);
       
  2552   }
       
  2553 
       
  2554   return false;
       
  2555 }
       
  2556 
       
  2557 // If the (growable) stack mapping already extends beyond the point
       
  2558 // where we're going to put our guard pages, truncate the mapping at
       
  2559 // that point by munmap()ping it.  This ensures that when we later
       
  2560 // munmap() the guard pages we don't leave a hole in the stack
       
  2561 // mapping.
       
  2562 bool os::create_stack_guard_pages(char* addr, size_t size) {
       
  2563   uintptr_t stack_extent, stack_base;
       
  2564   if (get_stack_bounds(&stack_extent, &stack_base)) {
       
  2565     if (stack_extent < (uintptr_t)addr)
       
  2566       ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent);
       
  2567   }
       
  2568 
       
  2569   return os::commit_memory(addr, size);
       
  2570 }
       
  2571 
       
  2572 // If this is a growable mapping, remove the guard pages entirely by
       
  2573 // munmap()ping them.  If not, just call uncommit_memory().
       
  2574 bool os::remove_stack_guard_pages(char* addr, size_t size) {
       
  2575   uintptr_t stack_extent, stack_base;
       
  2576   if (get_stack_bounds(&stack_extent, &stack_base)) {
       
  2577     return ::munmap(addr, size) == 0;
       
  2578   }
       
  2579 
       
  2580   return os::uncommit_memory(addr, size);
  2493 }
  2581 }
  2494 
  2582 
  2495 static address _highest_vm_reserved_address = NULL;
  2583 static address _highest_vm_reserved_address = NULL;
  2496 
  2584 
  2497 // If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory
  2585 // If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory