< prev index next >

src/os/linux/vm/os_linux.cpp

Print this page
rev 10456 : 8151593: Cleanup definition/usage of INLINE/NOINLINE macros and add xlC support
Contributed-by: matthias.baesken@sap.com


 576 //
 577 // There are two ways to expand thread stack to address "bottom", we used
 578 // both of them in JVM before 1.5:
 579 //   1. adjust stack pointer first so that it is below "bottom", and then
 580 //      touch "bottom"
 581 //   2. mmap() the page in question
 582 //
 583 // Now alternate signal stack is gone, it's harder to use 2. For instance,
 584 // if current sp is already near the lower end of page 101, and we need to
 585 // call mmap() to map page 100, it is possible that part of the mmap() frame
 586 // will be placed in page 100. When page 100 is mapped, it is zero-filled.
 587 // That will destroy the mmap() frame and cause VM to crash.
 588 //
 589 // The following code works by adjusting sp first, then accessing the "bottom"
 590 // page to force a page fault. Linux kernel will then automatically expand the
 591 // stack mapping.
 592 //
 593 // _expand_stack_to() assumes its frame size is less than page size, which
 594 // should always be true if the function is not inlined.
 595 
 596 #if __GNUC__ < 3    // gcc 2.x does not support noinline attribute
 597   #define NOINLINE
 598 #else
 599   #define NOINLINE __attribute__ ((noinline))
 600 #endif
 601 
 602 static void _expand_stack_to(address bottom) NOINLINE;
 603 
 604 static void _expand_stack_to(address bottom) {
 605   address sp;
 606   size_t size;
 607   volatile char *p;
 608 
 609   // Adjust bottom to point to the largest address within the same page, it
 610   // gives us a one-page buffer if alloca() allocates slightly more memory.
 611   bottom = (address)align_size_down((uintptr_t)bottom, os::Linux::page_size());
 612   bottom += os::Linux::page_size() - 1;
 613 
 614   // sp might be slightly above current stack pointer; if that's the case, we
 615   // will alloca() a little more space than necessary, which is OK. Don't use
 616   // os::current_stack_pointer(), as its result can be slightly below current
 617   // stack pointer, causing us to not alloca enough to reach "bottom".
 618   sp = (address)&sp;
 619 
 620   if (sp > bottom) {
 621     size = sp - bottom;
 622     p = (volatile char *)alloca(size);
 623     assert(p != NULL && p <= (volatile char *)bottom, "alloca problem?");
 624     p[0] = '\0';




 576 //
 577 // There are two ways to expand thread stack to address "bottom", we used
 578 // both of them in JVM before 1.5:
 579 //   1. adjust stack pointer first so that it is below "bottom", and then
 580 //      touch "bottom"
 581 //   2. mmap() the page in question
 582 //
 583 // Now alternate signal stack is gone, it's harder to use 2. For instance,
 584 // if current sp is already near the lower end of page 101, and we need to
 585 // call mmap() to map page 100, it is possible that part of the mmap() frame
 586 // will be placed in page 100. When page 100 is mapped, it is zero-filled.
 587 // That will destroy the mmap() frame and cause VM to crash.
 588 //
 589 // The following code works by adjusting sp first, then accessing the "bottom"
 590 // page to force a page fault. Linux kernel will then automatically expand the
 591 // stack mapping.
 592 //
 593 // _expand_stack_to() assumes its frame size is less than page size, which
 594 // should always be true if the function is not inlined.
 595 
 596 static void NOINLINE _expand_stack_to(address bottom) {








 597   address sp;
 598   size_t size;
 599   volatile char *p;
 600 
 601   // Adjust bottom to point to the largest address within the same page, it
 602   // gives us a one-page buffer if alloca() allocates slightly more memory.
 603   bottom = (address)align_size_down((uintptr_t)bottom, os::Linux::page_size());
 604   bottom += os::Linux::page_size() - 1;
 605 
 606   // sp might be slightly above current stack pointer; if that's the case, we
 607   // will alloca() a little more space than necessary, which is OK. Don't use
 608   // os::current_stack_pointer(), as its result can be slightly below current
 609   // stack pointer, causing us to not alloca enough to reach "bottom".
 610   sp = (address)&sp;
 611 
 612   if (sp > bottom) {
 613     size = sp - bottom;
 614     p = (volatile char *)alloca(size);
 615     assert(p != NULL && p <= (volatile char *)bottom, "alloca problem?");
 616     p[0] = '\0';


< prev index next >