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,65 @@ 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+ stackMemory = (UDATA)(stack + 1 );
1598+ stackMemory = ROUND_UP_TO_POWEROF2 (stackMemory, pageSize);
1599+
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+ }
15811615 }
1616+
15821617 if (stack != NULL ) {
15831618 /* for hyperthreading platforms, make sure that stacks are relatively misaligned */
1584- UDATA end = ((UDATA) stack) + J9_STACK_OVERFLOW_AND_HEADER_SIZE + stackSize ;
1619+ UDATA end = 0 ;
15851620 UDATA stagger = vm->thrStagger ;
1621+
1622+ if (pageGuards) {
1623+ end = stackMemory + J9_STACK_OVERFLOW_AND_HEADER_SIZE + stackSize;
1624+ if (end > ((UDATA)stack + mallocSize)) {
1625+ printf (" corruption\n " );
1626+ __asm__ (" int3" );
1627+
1628+ }
1629+ } else {
1630+ end = ((UDATA) stack) + J9_STACK_OVERFLOW_AND_HEADER_SIZE + stackSize;
1631+ }
1632+
15861633 stagger += vm->thrStaggerStep ;
15871634 vm->thrStagger = stagger = stagger >= vm->thrStaggerMax ? 0 : stagger;
15881635 if (vm->thrStaggerMax != 0 ) {
@@ -1613,7 +1660,12 @@ allocateJavaStack(J9JavaVM * vm, UDATA stackSize, J9JavaStack * previousStack)
16131660
16141661#if defined (J9VM_INTERP_VERBOSE) || defined (J9VM_PROF_EVENT_REPORTING)
16151662 if (vm->runtimeFlags & J9_RUNTIME_PAINT_STACK) {
1616- UDATA * currentSlot = (UDATA *) (stack + 1 );
1663+ UDATA *currentSlot = NULL ;
1664+ if (pageGuards) {
1665+ currentSlot = (UDATA *)stackMemory;
1666+ } else {
1667+ currentSlot = (UDATA *)(stack + 1 );
1668+ }
16171669
16181670 while (currentSlot != stack->end )
16191671 *currentSlot++ = J9_RUNTIME_STACK_FILL;
@@ -1626,10 +1678,19 @@ allocateJavaStack(J9JavaVM * vm, UDATA stackSize, J9JavaStack * previousStack)
16261678
16271679
16281680void
1629- freeJavaStack (J9JavaVM * vm, J9JavaStack * stack)
1681+ freeJavaStack (J9JavaVM *vm, J9JavaStack *stack)
16301682{
16311683 PORT_ACCESS_FROM_JAVAVM (vm);
1632-
1684+ if (J9_ARE_ALL_BITS_SET (vm->extendedRuntimeFlags3 , J9_EXTENDED_RUNTIME3_JAVA_STACK_GUARD_PAGES)) {
1685+ UDATA pageSize = vm->defaultPageSize ;
1686+ #if defined(LINUX)
1687+ if (0 != mprotect ((void *)stack->guardedPage , pageSize, PROT_READ|PROT_WRITE)) {
1688+ #elif defined(WINDOWS)
1689+ if (0 == VirtualProtect (stack->guardedPage , pageSize, 0 , NULL )) {
1690+ #endif
1691+ Assert_VM_unreachable ();
1692+ }
1693+ }
16331694 if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES (vm)) {
16341695 j9mem_free_memory32 (stack);
16351696 } else {
0 commit comments