2424
2525#include < string.h>
2626
27+ #if defined(LINUX)
28+ #include < sys/mman.h>
29+ #elif defined(WINDOWS)
30+ #include < windows.h>
31+ #endif
32+
2733#include " omrcfg.h"
2834#include " j9.h"
2935#include " j9cfg.h"
@@ -1565,24 +1571,66 @@ J9JavaStack *
15651571allocateJavaStack (J9JavaVM * vm, UDATA stackSize, J9JavaStack * previousStack)
15661572{
15671573 PORT_ACCESS_FROM_JAVAVM (vm);
1568- J9JavaStack * stack;
1569- UDATA mallocSize;
1574+ J9JavaStack *stack = NULL ;
1575+ UDATA mallocSize = 0 ;
1576+ UDATA pageSize = vm->defaultPageSize ;
1577+ bool pageGuards = J9_ARE_ALL_BITS_SET (vm->extendedRuntimeFlags3 , J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES);
1578+ UDATA stackMemory = 0 ;
15701579
15711580 /* Allocate the stack, adding the header and overflow area size.
15721581 * Add one slot for possible double-slot alignment.
15731582 * If stagger is in use, add the maximum stagger value to account for that alignment.
15741583 */
15751584
15761585 mallocSize = J9_STACK_OVERFLOW_AND_HEADER_SIZE + (stackSize + sizeof (UDATA)) + vm->thrStaggerMax ;
1586+ if (pageGuards) {
1587+ mallocSize += (pageSize * 2 );
1588+ }
1589+
15771590 if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES (vm)) {
1578- stack = (J9JavaStack*)j9mem_allocate_memory32 (mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK);
1591+ stack = (J9JavaStack *)j9mem_allocate_memory32 (mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK);
15791592 } else {
1580- stack = (J9JavaStack*)j9mem_allocate_memory (mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK);
1593+ stack = (J9JavaStack *)j9mem_allocate_memory (mallocSize, OMRMEM_CATEGORY_THREADS_RUNTIME_STACK);
1594+ }
1595+
1596+ if (pageGuards) {
1597+ if (NULL != stack) {
1598+ stackMemory = (UDATA)(stack + 1 );
1599+ stackMemory = ROUND_UP_TO_POWEROF2 (stackMemory, pageSize);
1600+ #if defined(LINUX)
1601+ if (0 == mprotect ((void *)stackMemory, pageSize, PROT_NONE)) {
1602+ #elif defined(WINDOWS)
1603+ if (0 != VirtualProtect (stackMemory, pageSize, PAGE_NOACCESS, &stack->defaultProtection )) {
1604+ #endif
1605+ stack->guardedPage = (UDATA *)stackMemory;
1606+ stackMemory += pageSize;
1607+ } else {
1608+ if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES (vm)) {
1609+ j9mem_free_memory32 (stack);
1610+ } else {
1611+ j9mem_free_memory (stack);
1612+ }
1613+ stack = NULL ;
1614+ }
1615+ }
15811616 }
1617+
15821618 if (stack != NULL ) {
15831619 /* for hyperthreading platforms, make sure that stacks are relatively misaligned */
1584- UDATA end = ((UDATA) stack) + J9_STACK_OVERFLOW_AND_HEADER_SIZE + stackSize ;
1620+ UDATA end = 0 ;
15851621 UDATA stagger = vm->thrStagger ;
1622+
1623+ if (pageGuards) {
1624+ end = stackMemory + J9_STACK_OVERFLOW_AND_HEADER_SIZE + stackSize;
1625+ if (end > ((UDATA)stack + mallocSize)) {
1626+ printf (" corruption\n " );
1627+ __asm__ (" int3" );
1628+
1629+ }
1630+ } else {
1631+ end = ((UDATA) stack) + J9_STACK_OVERFLOW_AND_HEADER_SIZE + stackSize;
1632+ }
1633+
15861634 stagger += vm->thrStaggerStep ;
15871635 vm->thrStagger = stagger = stagger >= vm->thrStaggerMax ? 0 : stagger;
15881636 if (vm->thrStaggerMax != 0 ) {
@@ -1613,7 +1661,12 @@ allocateJavaStack(J9JavaVM * vm, UDATA stackSize, J9JavaStack * previousStack)
16131661
16141662#if defined (J9VM_INTERP_VERBOSE) || defined (J9VM_PROF_EVENT_REPORTING)
16151663 if (vm->runtimeFlags & J9_RUNTIME_PAINT_STACK) {
1616- UDATA * currentSlot = (UDATA *) (stack + 1 );
1664+ UDATA *currentSlot = NULL ;
1665+ if (pageGuards) {
1666+ currentSlot = (UDATA *)stackMemory;
1667+ } else {
1668+ currentSlot = (UDATA *)(stack + 1 );
1669+ }
16171670
16181671 while (currentSlot != stack->end )
16191672 *currentSlot++ = J9_RUNTIME_STACK_FILL;
@@ -1626,10 +1679,19 @@ allocateJavaStack(J9JavaVM * vm, UDATA stackSize, J9JavaStack * previousStack)
16261679
16271680
16281681void
1629- freeJavaStack (J9JavaVM * vm, J9JavaStack * stack)
1682+ freeJavaStack (J9JavaVM *vm, J9JavaStack *stack)
16301683{
16311684 PORT_ACCESS_FROM_JAVAVM (vm);
1632-
1685+ if (J9_ARE_ALL_BITS_SET (vm->extendedRuntimeFlags3 , J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES)) {
1686+ UDATA pageSize = vm->defaultPageSize ;
1687+ #if defined(LINUX)
1688+ if (0 != mprotect ((void *)stack->guardedPage , pageSize, PROT_READ|PROT_WRITE)) {
1689+ #elif defined(WINDOWS)
1690+ if (0 == VirtualProtect (stack->guardedPage , pageSize, 0 , NULL )) {
1691+ #endif
1692+ Assert_VM_unreachable ();
1693+ }
1694+ }
16331695 if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES (vm)) {
16341696 j9mem_free_memory32 (stack);
16351697 } else {
0 commit comments